private void getElements(IBSTNode currNode, BSTStack stack) { // add nodes into stack to use at getEnumerator() // null nodes not allowed if (currNode == null) { return; } if (currNode.isLeaf()) { // add element to stack stack.Push(currNode); } else { // unbox BSTInternalNode node = (BSTInternalNode)currNode; // get left node this.getElements(node.Left, stack); // add current element to stack stack.Push(node); // get right nodes this.getElements(node.Right, stack); } }
private IBSTNode SearchNode(IBSTNode currNode, int key, ref int iterations) { iterations++; // key not found if (currNode == null) { return(null); } // key found if (currNode.Key == key) { return(currNode); } // at this point, if current node is leaf, value not found if (currNode.isLeaf()) { return(null); } // redirect to left or right branch return(this.SearchNode(key > currNode.Key ? ((BSTInternalNode)currNode).Left : ((BSTInternalNode)currNode).Right, key, ref iterations)); }
private int CountNodes(IBSTNode currNode, int count) { // check if current node is null if (currNode == null) { return(count); } // increment count count++; // check if current node is leaf if (currNode.isLeaf()) { return(count); } // current node is internal, unbox it BSTInternalNode node = (BSTInternalNode)currNode; // go to left branch count = this.CountNodes(node.Left, count); // go to right branch count = this.CountNodes(node.Right, count); return(count); }
/// <summary> /// Removes element associated to the key argument. /// </summary> /// <param name="key">The key of the element to be removed.</param> /// <returns>True if element is removed, falso if key not found.</returns> public bool Remove(int key) { // removes element from list based on key int iter = 0; // no use in this context // first stpe, find node to be removed IBSTNode node = this.SearchNode(this._root, key, ref iter); // key not found if (node == null) { return(false); } // if node is leaf, remove reference from parent and that's all // or if it's root, set to null if (node.isLeaf()) { if (node.Status == BSTNodeStatus.Root) { this._root = null; } else if (node.Status == BSTNodeStatus.Left) { ((BSTInternalNode)node.Parent).Left = null; } else { ((BSTInternalNode)node.Parent).Right = null; } } else if (node.isRoot()) // check if node is root { // add reference to children IBSTNode leftSubtree = ((BSTInternalNode)this._root).Left; IBSTNode rightSubtree = ((BSTInternalNode)this._root).Right; // check if left subtree is empty, if not, it becomes the new tree if (leftSubtree != null) { leftSubtree.Parent = null; // erase reference to old parent this._root = leftSubtree; // find an empty spot to accomodate the right subtree // if it is not null if (rightSubtree != null) { this.InsertNode(this._root, rightSubtree); } } else { // right subtree is the new tree // at this point it can't be null rightSubtree.Parent = null; this._root = rightSubtree; } } else { // add reference to children IBSTNode leftSubtree = ((BSTInternalNode)node).Left; IBSTNode rightSubtree = ((BSTInternalNode)node).Right; // remove reference from parent if (node.Status == BSTNodeStatus.Left) { ((BSTInternalNode)node.Parent).Left = null; } else { ((BSTInternalNode)node.Parent).Right = null; } // find new location for subtees if (leftSubtree != null) { this.InsertNode(this._root, leftSubtree); } if (rightSubtree != null) { this.InsertNode(this._root, rightSubtree); } } // decrement count this._count--; return(true); }
private void InsertNode(IBSTNode currNode, IBSTNode node) { // neither current node nor node can be null if (currNode == null) { throw new ArgumentNullException("currNode"); } else if (node == null) { throw new ArgumentNullException("node"); } // if current node is a leaf, convert it to internal and repeat process if (currNode.isLeaf()) { if (currNode.isRoot()) { // current node is root and leaf // convert root to internal node (no parent reference) this._root = new BSTInternalNode(this._root.Key, this._root.Value); // add node to it this.InsertNode(this._root, node); } else { // unbox parent BSTInternalNode parent = (BSTInternalNode)currNode.Parent; // create new internal BSTInternalNode newIntNode = new BSTInternalNode(currNode.Key, currNode.Value, parent); // add child to right side of the tree if (parent.Left == currNode) { parent.Left = newIntNode; } else { parent.Right = newIntNode; } // add node to it this.InsertNode(newIntNode, node); } } else { // unbox current node BSTInternalNode currIntNode = (BSTInternalNode)currNode; if (node.Key > currIntNode.Key) { // check if left child is empty if (currIntNode.Left == null) { // location found currIntNode.Left = node; // add parent reference node.Parent = currIntNode; } else { // curent node is left this.InsertNode(currIntNode.Left, node); } } else { // check if right child is empty if (currIntNode.Right == null) { // location found currIntNode.Right = node; // add parent reference node.Parent = currIntNode; } else { // curent node is right this.InsertNode(currIntNode.Right, node); } } } }
private void InsertNewLeafNode(IBSTNode currNode, int key, string value) { // current node cannot be null if (currNode == null) { throw new ArgumentNullException("currNode"); } // if value is the same, duplicate key found, replace value. if (currNode.Key == key) { currNode.Value = value; return; } // check if node is a leaf if (currNode.isLeaf()) { // check if current node is root if (currNode.isRoot()) { // convert leaf into internal with the same parameters this._root = new BSTInternalNode(this._root.Key, this._root.Value); // insert new leaf node this.InsertNewLeafNode(this._root, key, value); } else { // unbox parent BSTInternalNode parent = (BSTInternalNode)currNode.Parent; // create new internal node using current value BSTInternalNode newIntNode = new BSTInternalNode(currNode.Key, currNode.Value, parent); // replace old leaf with new internal // add reference to correct branch of parent if (parent.Left == currNode) { parent.Left = newIntNode; } else { parent.Right = newIntNode; } // insert new leaf node this.InsertNewLeafNode(newIntNode, key, value); } } else { // current node not leaf, unbox it BSTInternalNode node = (BSTInternalNode)currNode; // redirect to correct branch if (key > node.Key) { // check if left child is empty, if so add new leaf if (node.Left == null) { node.Left = new BSTLeafNode(key, value, node); this._count++; } else { this.InsertNewLeafNode(node.Left, key, value); // redirect to left branch } } else { // check if right child is empty, if so add new leaf if (node.Right == null) { node.Right = new BSTLeafNode(key, value, node); this._count++; } else { this.InsertNewLeafNode(node.Right, key, value); // redirect to right branch } } } }