/// <summary> /// Initializes the ArrayList class. /// </summary> static ArrayList() { IAvlNode parent = AvlNode.NullNode; IAvlNode child = AvlNode.NullNode; // Create the tree pool. for (int i = 0; i < TreePoolHeight; i++) { parent = new AvlNode(null, child, child); child = parent; } TreePool = parent; // Postconditions. Debug.Assert(TreePool.Height == TreePoolHeight); }
private IAvlNode CollectionToTree(IEnumerator enumerator, int height) { IAvlNode result; if (height == 0) { object data = null; if (enumerator.MoveNext()) { data = enumerator.Current; } result = new AvlNode( data, AvlNode.NullNode, AvlNode.NullNode); } else { IAvlNode leftChild, rightChild; object data = null; leftChild = CollectionToTree(enumerator, height - 1); if (enumerator.MoveNext()) { data = enumerator.Current; rightChild = CollectionToTree(enumerator, height - 1); } else { rightChild = GetSubTree(height - 1); } result = new AvlNode( data, leftChild, rightChild); } Debug.Assert(result.IsBalanced()); return(result); }
/// <summary> /// Removes the current node from the AVL tree. /// </summary> /// <returns> /// The node to in the tree to replace the current node. /// </returns> public IAvlNode Remove() { IAvlNode result; /* * Deal with the three cases for removing a node from a binary tree. */ // If the node has no right children. if (this.RightChild == AvlNode.NullNode) { // The replacement node is the node's left child. result = this.LeftChild; } // Else if the node's right child has no left children. else if (this.RightChild.LeftChild == AvlNode.NullNode) { // The replacement node is the node's right child. result = new AvlNode( this.RightChild.Data, this.LeftChild, this.RightChild.RightChild); } // Else the node's right child has left children. else { /* * Go to the node's right child and descend as far left as * possible. The node found at this point will replace the * node to be removed. */ IAvlNode replacement = AvlNode.NullNode; IAvlNode rightChild = RemoveReplacement(this.RightChild, ref replacement); // Create new node with the replacement node and the new // right child. result = new AvlNode( replacement.Data, this.LeftChild, rightChild); } return(result); }
// Recursive SetValue helper method. private IAvlNode SetValue(int index, object value, IAvlNode node) { // Preconditions. Debug.Assert(index >= 0 && index < node.Count); Debug.Assert(node != AvlNode.NullNode); IAvlNode result; int leftCount = node.LeftChild.Count; // If the node has been found. if (index == leftCount) { // Create new node with the new value. result = new AvlNode(value, node.LeftChild, node.RightChild); } // Else if the node is in the left tree. else if (index < leftCount) { // Create new node and move search to the left child. The new // node will reuse the right child subtree. result = new AvlNode( node.Data, SetValue(index, value, node.LeftChild), node.RightChild); } // Else if the node is in the right tree. else { // Create new node and move search to the right child. The new // node will reuse the left child subtree. result = new AvlNode( node.Data, node.LeftChild, SetValue(index - (leftCount + 1), value, node.RightChild)); } return(result); }
// Right - left double rotation. private IAvlNode DoRLRotation(IAvlNode node) { /* * An RL rotation looks like the following: * * Perform an LL rotation at B: * * A A * \ \ * B ---> C * / \ * C B * * Perform an RR rotation at A: * * A C * \ / \ * C ---> A B * \ * B */ IAvlNode a = new AvlNode( node.Data, node.LeftChild, DoLLRotation(node.RightChild)); IAvlNode c = DoRRRotation(a); // Postconditions. Debug.Assert(c.Data == node.RightChild.LeftChild.Data); Debug.Assert(c.LeftChild.Data == node.Data); Debug.Assert(c.RightChild.Data == node.RightChild.Data); return(c); }
// Recursive Insert helper method. private IAvlNode Insert(int index, object value, IAvlNode node) { // Preconditions. Debug.Assert(index >= 0 && index <= Count); Debug.Assert(node != null); /* * The insertion algorithm searches for the correct place to add a * new node at the bottom of the tree using the specified index. */ IAvlNode result; // If the bottom of the tree has not yet been reached. if (node != AvlNode.NullNode) { int leftCount = node.LeftChild.Count; // If we need to descend to the left. if (index <= leftCount) { // Create new node and move search to the left child. The // new node will reuse the right child subtree. result = new AvlNode( node.Data, Insert(index, value, node.LeftChild), node.RightChild); } // Else we need to descend to the right. else { // Create new node and move search to the right child. The // new node will reuse the left child subtree. result = new AvlNode( node.Data, node.LeftChild, Insert(index - (leftCount + 1), value, node.RightChild)); } } // Else the bottom of the tree has been reached. else { // Create new node at the specified index. result = new AvlNode(value, AvlNode.NullNode, AvlNode.NullNode); } /* * This check isn't necessary if a node has already been rebalanced * after an insertion. AVL tree insertions never require more than * one rebalancing. However, it's easier to go ahead and check at * this point since we're using recursion. This may need optimizing * in the future. */ // If the node is not balanced. if (!result.IsBalanced()) { // Rebalance node. result = result.Balance(); } // Postconditions. Debug.Assert(result.IsBalanced()); return(result); }