private void New(TKey key, TValue data) { if (data == null) { throw new Exception(); } // create new node var newNode = new RedBlackNode <TKey, TValue>(key, data); var workNode = _root; while (!workNode.IsSentinel) { // find Parent newNode.Parent = workNode; int result = key.CompareTo(workNode.Key); if (result == 0) { throw new Exception(); } workNode = result > 0 ? workNode.Right : workNode.Left; } // insert node into tree starting at parent's location if (newNode.Parent != null) { if (newNode.Key.CompareTo(newNode.Parent.Key) > 0) { newNode.Parent.Right = newNode; } else { newNode.Parent.Left = newNode; } } else { _root = newNode; } // restore red-black properties BalanceTreeAfterInsert(newNode); }
private static int MaxDepthInternal(RedBlackNode <TKey, TValue> node) { if (node.IsSentinel) { return(0); } /* compute the depth of each subtree */ var lDepth = MaxDepthInternal(node.Left); var rDepth = MaxDepthInternal(node.Right); /* use the larger one */ if (lDepth > rDepth) { return(lDepth + 1); } return(rDepth + 1); }
private bool isValidRBT(RedBlackNode <TKey, TValue> node, TKey low, TKey high) { if (node.IsSentinel) { return(true); } bool isLow = false; bool isHigh = false; if (node.Key.CompareTo(low) > 0) { isLow = true; } if (node.Key.CompareTo(high) < 0) { isHigh = true; } return(isLow && isHigh && isValidRBT(node.Left, low, node.Key) && isValidRBT(node.Right, node.Key, high)); }
private void RotateLeft(RedBlackNode <TKey, TValue> rotateNode) { var workNode = rotateNode.Right; rotateNode.Right = workNode.Left; if (!workNode.Left.IsSentinel) { workNode.Left.Parent = rotateNode; } if (!workNode.IsSentinel) { workNode.Parent = rotateNode.Parent; } if (rotateNode.Parent != null) { if (rotateNode == rotateNode.Parent.Left) { rotateNode.Parent.Left = workNode; } else { rotateNode.Parent.Right = workNode; } } else { _root = workNode; } workNode.Left = rotateNode; if (!rotateNode.IsSentinel) { rotateNode.Parent = workNode; } }
private void BalanceTreeAfterDelete(RedBlackNode <TKey, TValue> linkedNode) { while (linkedNode != _root && linkedNode.Color == RedBlackNodeType.Black) { RedBlackNode <TKey, TValue> workNode; if (linkedNode == linkedNode.Parent.Left) { workNode = linkedNode.Parent.Right; if (workNode.Color == RedBlackNodeType.Red) { linkedNode.Parent.Color = RedBlackNodeType.Red; workNode.Color = RedBlackNodeType.Black; RotateLeft(linkedNode.Parent); workNode = linkedNode.Parent.Right; } if (workNode.Left.Color == RedBlackNodeType.Black && workNode.Right.Color == RedBlackNodeType.Black) { workNode.Color = RedBlackNodeType.Red; linkedNode = linkedNode.Parent; } else { if (workNode.Right.Color == RedBlackNodeType.Black) { workNode.Left.Color = RedBlackNodeType.Black; workNode.Color = RedBlackNodeType.Red; RotateRight(workNode); workNode = linkedNode.Parent.Right; } workNode.Color = linkedNode.Parent.Color; linkedNode.Parent.Color = RedBlackNodeType.Black; workNode.Right.Color = RedBlackNodeType.Black; RotateLeft(linkedNode.Parent); linkedNode = _root; } } else { // right subtree - same as code above with right and left swapped workNode = linkedNode.Parent.Left; if (workNode.Color == RedBlackNodeType.Red) { linkedNode.Parent.Color = RedBlackNodeType.Red; workNode.Color = RedBlackNodeType.Black; RotateRight(linkedNode.Parent); workNode = linkedNode.Parent.Left; } if (workNode.Right.Color == RedBlackNodeType.Black && workNode.Left.Color == RedBlackNodeType.Black) { workNode.Color = RedBlackNodeType.Red; linkedNode = linkedNode.Parent; } else { if (workNode.Left.Color == RedBlackNodeType.Black) { workNode.Right.Color = RedBlackNodeType.Black; workNode.Color = RedBlackNodeType.Red; RotateLeft(workNode); workNode = linkedNode.Parent.Left; } workNode.Color = linkedNode.Parent.Color; linkedNode.Parent.Color = RedBlackNodeType.Black; workNode.Left.Color = RedBlackNodeType.Black; RotateRight(linkedNode.Parent); linkedNode = _root; } } } linkedNode.Color = RedBlackNodeType.Black; }