//Following methods are helper method for treeBalancing method //Should not be used anywhere else. #region Tree Balancing Helper methods /// <summary> /// private helper method: Hook up the node with the tree after apply supplied rotation function rotation /// </summary> /// <param name="stack"> the stack used to retrace the node visited </param> /// <param name="node"> the node currently in processing</param> /// <param name="func"> the rotation function</param> private void HookUp(Stack <AvlNode <T> > stack, AvlNode <T> node, Func <AvlNode <T>, AvlNode <T> > func) { if (stack.Count > 0) { if (stack.Peek().Left != null && stack.Peek().Left.Data.CompareTo(node.Data) == 0) { stack.Peek().Left = func(node); return; } stack.Peek().Right = func(node); return; } Root = func(node); }
/// <summary> /// private helper method: calculate the balancing factor of given node /// </summary> /// <param name="node"> node need to calculate balancing factor</param> /// <returns></returns> private int GetBalancingFactor(AvlNode <T> node) { //no child, balancing factor is 0 if (node.IsLeafNode()) { return(0); } //has two child, balancing factor is height of left subtree - height of right subtree if (!node.HasOneChild()) { return(node.Left.Height - node.Right.Height); } //only one child, return that child's height if (node.Left != null) //child on the left { return(node.Left.Height); } return(0 - node.Right.Height); //child on the right }
/// <summary> /// Insert new data into AVL Tree. /// If data is actually inserted, method will return true. /// If duplicate data is found, duplicate data will not be inserted and method will return false. /// </summary> /// <param name="data">The data intended to be insert into this AVL Tree.</param> /// <returns></returns> public override bool Insert(T data) { //handling an empty tree if (Root == null) { Root = new AvlNode <T>(data) { Height = 1 }; TreeSize++; return(true); } var res = true; var current = Root; // use stack keep record of traverse path var stack = new Stack <AvlNode <T> >(); stack.Push(current); while (true) { // Data to be inserted is smaller then current node, go left if (data.CompareTo(current.Data) < 0) { if (current.Left != null) { current = current.Left; stack.Push(current); continue; } // if has no left child, insert new node here current.Left = new AvlNode <T>(data); stack.Push(current.Left); break; } // Duplicate data is not allowed in BST, if found, stop insertion and return false; if (data.CompareTo(current.Data) == 0) { res = false; break; } // Data to be inserted is bigger then current node, go right if (current.Right != null) { current = current.Right; stack.Push(current); continue; } // If has no right child, insert new node here current.Right = new AvlNode <T>(data); stack.Push(current.Right); break; } if (res) { // if data inserted, increase tree size and balancing the tree TreeSize++; TreeBalancing(stack); } return(res); }
/// <summary> /// Constructor of AVLTree with root node's data specified /// this constructor creates an AVLTree contains only root node which holds specified data /// </summary> /// <param name="data"> the actual data the root node should hold </param> public AvlTree(T data) { Root = new AvlNode <T>(data); TreeSize++; }