private RbNode InsertionBalance(RbNode current, RbNode parent, RbNode grandParent, RbNode greatGrandParent) { var parentIsOnRight = (grandParent.Right == parent); var currentIsOnRight = (parent.Right == current); RbNode newChildOfGreatGrandParent; if (parentIsOnRight == currentIsOnRight) { // same orientation, single rotation newChildOfGreatGrandParent = currentIsOnRight ? RotateLeft(grandParent) : RotateRight(grandParent); } else { // different orientaton, double rotation newChildOfGreatGrandParent = (currentIsOnRight ? RotateLeftRight(grandParent) : RotateRightLeft(grandParent)); // current node now becomes the child of greatgrandparent parent = greatGrandParent; } // grand parent will become a child of either parent of current. grandParent.IsRed = true; newChildOfGreatGrandParent.IsRed = false; ReplaceChildOrRoot(greatGrandParent, grandParent, newChildOfGreatGrandParent); return(parent); }
private RbNode RotateLeft(RbNode node) { var x = node.Right; node.Right = x.Left; x.Left = node; return(x); }
private RbNode RotateRightLeft(RbNode node) { var child = node.Right; var grandChild = child.Left; node.Right = grandChild.Left; grandChild.Left = node; child.Left = grandChild.Right; grandChild.Right = child; return(grandChild); }
private void ReplaceChildOrRoot(RbNode parent, RbNode child, RbNode newChild) { if (parent != null) { if (parent.Left == child) { parent.Left = newChild; } else { parent.Right = newChild; } } else { _root = newChild; } }
private IEnumerable <RbNode> InOrderTravers(RbNode node) { /* * iterativeInorder(node) * parentStack = empty stack * while (not parentStack.isEmpty() or node ≠ null) * if (node ≠ null) * parentStack.push(node) * node = node.left * else * node = parentStack.pop() * visit(node) * node = node.right */ if (node == null) { yield break; } var capacity = 2 * (int)Math.Log(_count + 1, 2); var parentStack = new Stack <RbNode>(capacity); while (parentStack.Count > 0 || node != null) { if (node != null) { parentStack.Push(node); node = node.Left; } else { node = parentStack.Pop(); yield return(node); node = node.Right; } } }
public void Add(int index) { if (_root == null) { _root = new RbNode(index, false); return; } var current = _root; var parent = (RbNode)null; var grandParent = (RbNode)null; var greatGrandParent = (RbNode)null; var order = 0; while (current != null) { order = CompareItems(index, current.Index); if (order == 0) { _root.IsRed = false; _count++; return; } if (Is4Node(current)) { Split4Node(current); if (IsRed(parent)) { parent = InsertionBalance(current, parent, grandParent, greatGrandParent); } } greatGrandParent = grandParent; grandParent = parent; parent = current; current = (order < 0) ? current.Left : current.Right; } var node = new RbNode(index); if (order > 0) { parent.Right = node; } else { parent.Left = node; } if (parent.IsRed) { parent = InsertionBalance(node, parent, grandParent, greatGrandParent); } _root.IsRed = false; _count++; }
private void Split4Node(RbNode node) { node.IsRed = true; node.Left.IsRed = false; node.Right.IsRed = false; }
private bool Is4Node(RbNode node) { return(IsRed(node.Left) && IsRed(node.Right)); }
private bool IsRed(RbNode node) { return(node != null && node.IsRed); }