/// <summary> Insert into the tree. Does nothing if item already present. /// </summary> /// <param name="item">the item to insert. /// </param> public virtual void Insert(IComparable item) { current = parent = grand = header; nullNode.element = item; while (current.element.CompareTo(item) != 0) { great = grand; grand = parent; parent = current; current = item.CompareTo(current.element) < 0?current.left:current.right; // Check if two red children; fix if so if (current.left.color == RED && current.right.color == RED) handleReorient(item); } // Insertion fails if already present if (current != nullNode) return ; current = new RedBlackNode(item, nullNode, nullNode); // Attach to parent if (item.CompareTo(parent.element) < 0) parent.left = current; else parent.right = current; handleReorient(item); }
/// <summary> Double rotate binary tree node: first right child /// with its left child; then node k1 with new right child. /// For AVL trees, this is a double rotation for case 3. /// </summary> internal static RedBlackNode doubleWithRightChild(RedBlackNode k1) { k1.right = withLeftChild(k1.right); return withRightChild(k1); }
/// <summary> Construct the tree. /// </summary> /// <param name="negInf">a value less than or equal to all others. /// </param> public RedBlackTree(IComparable negInf) { header = new RedBlackNode(negInf); header.left = header.right = nullNode; }
/// <summary> Rotate binary tree node with right child. /// For AVL trees, this is a single rotation for case 4. /// </summary> internal static RedBlackNode withRightChild(RedBlackNode k1) { RedBlackNode k2 = k1.right; k1.right = k2.left; k2.left = k1; return k2; }
/// <summary> Double rotate binary tree node: first left child /// with its right child; then node k3 with new left child. /// For AVL trees, this is a double rotation for case 2. /// </summary> internal static RedBlackNode doubleWithLeftChild(RedBlackNode k3) { k3.left = withRightChild(k3.left); return withLeftChild(k3); }
/// <summary> Rotate binary tree node with left child. /// For AVL trees, this is a single rotation for case 1. /// </summary> internal static RedBlackNode withLeftChild(RedBlackNode k2) { RedBlackNode k1 = k2.left; k2.left = k1.right; k1.right = k2; return k1; }
internal RedBlackNode(IComparable theElement, RedBlackNode lt, RedBlackNode rt) { element = theElement; left = lt; right = rt; color = RedBlackTree.BLACK; }
// // Test program // [STAThread] // public static void Main(System.String[] args) // { // RedBlackTree t = new RedBlackTree(new MyInteger(System.Int32.MinValue)); // int NUMS = 40000; // int GAP = 307; // // System.Console.Out.WriteLine("Checking... (no more output means success)"); // // for (int i = GAP; i != 0; i = (i + GAP) % NUMS) // t.Insert(new MyInteger(i)); // // if (NUMS < 40) // t.PrintTree(); // if (((MyInteger) (t.FindMin())).intValue() != 1 || ((MyInteger) (t.FindMax())).intValue() != NUMS - 1) // System.Console.Out.WriteLine("FindMin or FindMax error!"); // // for (int i = 1; i < NUMS; i++) // if (((MyInteger) (t.Find(new MyInteger(i)))).intValue() != i) // System.Console.Out.WriteLine("Find error1!"); // } static RedBlackTree() { nullNode = new RedBlackNode(null); nullNode.left = nullNode.right = nullNode; }
/// <summary> Internal routine that performs a single or double rotation. /// Because the result is attached to the parent, there are four cases. /// Called by handleReorient. /// </summary> /// <param name="item">the item in handleReorient. /// </param> /// <param name="parent">the parent of the root of the rotated subtree. /// </param> /// <returns> the root of the rotated subtree.</returns> private RedBlackNode rotate(IComparable item, RedBlackNode parent) { if (item.CompareTo(parent.element) < 0) return parent.left = item.CompareTo(parent.left.element) < 0?rotateWithLeftChild(parent.left):rotateWithRightChild(parent.left); // LR else return parent.right = item.CompareTo(parent.right.element) < 0?rotateWithLeftChild(parent.right):rotateWithRightChild(parent.right); // RR }
/// <summary> Internal method to print a subtree in sorted order. /// </summary> /// <param name="t">the node that roots the tree. /// /// </param> private void PrintTree(RedBlackNode t) { if (t != nullNode) { PrintTree(t.left); System.Console.Out.WriteLine(t.element); PrintTree(t.right); } }