/// <summary> /// Remove the specified node. /// </summary> protected virtual bool _remove(BSTMapNode <TKey, TValue> node) { if (node == null) { return(false); } var parent = node.Parent; if (node.ChildrenCount == 2) // if both children are present { var successor = node.RightChild; node.Key = successor.Key; node.Value = successor.Value; return(true && _remove(successor)); } else if (node.HasLeftChild) // if the node has only a LEFT child { _replaceNodeInParent(node, node.LeftChild); _count--; } else if (node.HasRightChild) // if the node has only a RIGHT child { _replaceNodeInParent(node, node.RightChild); _count--; } else //this node has no children { _replaceNodeInParent(node, null); _count--; } return(true); }
/// <summary> /// Calculates the tree height from a specific node, recursively. /// Time-complexity: O(n), where n = number of nodes. /// </summary> protected virtual int _getTreeHeight(BSTMapNode <TKey, TValue> node) { if (node == null) { return(0); } // Is leaf node else if (node.IsLeafNode) { return(1); } // Has two children else if (node.ChildrenCount == 2) { return(1 + Math.Max(_getTreeHeight(node.LeftChild), _getTreeHeight(node.RightChild))); } // Has only left else if (node.HasLeftChild) { return(1 + _getTreeHeight(node.LeftChild)); } // Has only right else { return(1 + _getTreeHeight(node.RightChild)); } }
/// <summary> /// Inserts a new node to the tree. /// </summary> protected virtual bool _insertNode(BSTMapNode <TKey, TValue> newNode) { // Handle empty trees if (this.Root == null) { Root = newNode; _count++; return(true); } else { if (newNode.Parent == null) { newNode.Parent = this.Root; } // Check for value equality and whether inserting duplicates is allowed if (_allowDuplicates == false && newNode.Parent.Key.IsEqualTo(newNode.Key)) { return(false); } // Go Left if (newNode.Parent.Key.IsGreaterThan(newNode.Key)) // newNode < parent { if (newNode.Parent.HasLeftChild == false) { newNode.Parent.LeftChild = newNode; // Increment count. _count++; return(true); } else { newNode.Parent = newNode.Parent.LeftChild; return(_insertNode(newNode)); } } // Go Right else // new node > parent { if (newNode.Parent.HasRightChild == false) { newNode.Parent.RightChild = newNode; // Increment count. _count++; return(true); } else { newNode.Parent = newNode.Parent.RightChild; return(_insertNode(newNode)); } } } }
/// <summary> /// Finds a node inside another node's subtrees, given it's value. /// </summary> protected virtual BSTMapNode <TKey, TValue> _findNode(BSTMapNode <TKey, TValue> currentNode, TKey key) { if (currentNode == null) { return(currentNode); } if (key.IsEqualTo(currentNode.Key)) { return(currentNode); } if (currentNode.HasLeftChild && key.IsLessThan(currentNode.Key)) { return(_findNode(currentNode.LeftChild, key)); } if (currentNode.HasRightChild && key.IsGreaterThan(currentNode.Key)) { return(_findNode(currentNode.RightChild, key)); } // Return-functions-fix return(null); }
public BSTMapNode(TKey key, TValue value, int subTreeSize, BSTMapNode <TKey, TValue> parent, BSTMapNode <TKey, TValue> left, BSTMapNode <TKey, TValue> right) { Key = key; Value = value; Parent = parent; LeftChild = left; RightChild = right; }
/// <summary> /// Compares to. /// </summary> public virtual int CompareTo(BSTMapNode <TKey, TValue> other) { if (other == null) { return(-1); } return(this.Key.CompareTo(other.Key)); }
private void visitNode(BSTMapNode <TKey, TValue> node) { if (node == null) { return; } visitNode(node.LeftChild); visitNode(node.RightChild); traverseQueue.Enqueue(node); }
/// <summary> /// Inserts a key-value pair to the tree /// </summary> public virtual void Insert(TKey key, TValue value) { var newNode = new BSTMapNode <TKey, TValue>(key, value); // Insert node recursively starting from the root. check for success status. var success = _insertNode(newNode); if (success == false && _allowDuplicates == false) { throw new InvalidOperationException("Tree does not allow inserting duplicate elements."); } }
public bool MoveNext() { if (traverseQueue.Count > 0) { current = traverseQueue.Dequeue(); } else { current = null; } return(current != null); }
/// <summary> /// Returns the max-node in a subtree. /// Used in the recusive _remove function. /// </summary> protected virtual BSTMapNode <TKey, TValue> _findMaxNode(BSTMapNode <TKey, TValue> node) { if (node == null) { return(node); } var currentNode = node; while (currentNode.HasRightChild) { currentNode = currentNode.RightChild; } return(currentNode); }
/// <summary> /// In-order traversal of the subtrees of a node. Returns every node it vists. /// </summary> protected virtual void _inOrderTraverse(BSTMapNode <TKey, TValue> currentNode, ref List <KeyValuePair <TKey, TValue> > list) { if (currentNode == null) { return; } // call the left child _inOrderTraverse(currentNode.LeftChild, ref list); // visit node list.Add(new KeyValuePair <TKey, TValue>(currentNode.Key, currentNode.Value)); // call the right child _inOrderTraverse(currentNode.RightChild, ref list); }
/// <summary> /// A recursive private method. Used in the public FindAll(predicate) functions. /// Implements in-order traversal to find all the matching elements in a subtree. /// </summary> protected virtual void _findAll(BSTMapNode <TKey, TValue> currentNode, Predicate <TKey> match, ref List <KeyValuePair <TKey, TValue> > list) { if (currentNode == null) { return; } // call the left child _findAll(currentNode.LeftChild, match, ref list); if (match(currentNode.Key)) // match { list.Add(new KeyValuePair <TKey, TValue>(currentNode.Key, currentNode.Value)); } // call the right child _findAll(currentNode.RightChild, match, ref list); }
/// <summary> /// Replaces the node's value from it's parent node object with the newValue. /// Used in the recusive _remove function. /// </summary> protected virtual void _replaceNodeInParent(BSTMapNode <TKey, TValue> node, BSTMapNode <TKey, TValue> newNode = null) { if (node.Parent != null) { if (node.IsLeftChild) { node.Parent.LeftChild = newNode; } else { node.Parent.RightChild = newNode; } } if (newNode != null) { newNode.Parent = node.Parent; } }
/// <summary> /// Finds the next smaller node in value compared to the specified node. /// </summary> protected virtual BSTMapNode <TKey, TValue> _findNextSmaller(BSTMapNode <TKey, TValue> node) { if (node == null) { return(node); } if (node.HasLeftChild) { return(_findMaxNode(node.LeftChild)); } var currentNode = node; while (currentNode.Parent != null && currentNode.IsLeftChild) { currentNode = currentNode.Parent; } return(currentNode.Parent); }
/// <summary> /// Finds the next larger node in value compared to the specified node. /// </summary> protected virtual BSTMapNode <TKey, TValue> _findNextLarger(BSTMapNode <TKey, TValue> node) { if (node == null) { return(node); } if (node.HasRightChild) { return(_findMinNode(node.RightChild)); } var currentNode = node; while (currentNode.Parent != null && currentNode.IsRightChild) { currentNode = currentNode.Parent; } return(currentNode.Parent); }
/// <summary> /// Remove node helpers. /// </summary> protected override bool _remove(BSTMapNode <TKey, TValue> nodeToDelete) { return(this._remove((RedBlackTreeMapNode <TKey, TValue>)nodeToDelete)); }
private static List <string> _recursivelyDrawTree <TKey, TValue> (BSTMapNode <TKey, TValue> node, out int positionOutput, out int widthOutput, bool includeValues = false) where TKey : IComparable <TKey> { widthOutput = 0; positionOutput = 0; var listOfLines = new List <string>(); if (node == null) { return(listOfLines); } // // Variables var nodeLabel = ""; var padValue = 0; List <string> leftLines, rightLines; leftLines = rightLines = new List <string>(); int leftPosition = 0, rightPosition = 0; int leftWidth = 0, rightWidth = 0; int middle, position_out, width_out; // // Start drawing if (includeValues) { nodeLabel = string.Format("<{0}: {1}>", Convert.ToString(node.Key), Convert.ToString(node.Value)); padValue = 4; } else { nodeLabel = Convert.ToString(node.Key); padValue = 2; } // Visit the left child leftLines = _recursivelyDrawTree(node.LeftChild, out leftPosition, out leftWidth, includeValues); // Visit the right child rightLines = _recursivelyDrawTree(node.RightChild, out rightPosition, out rightWidth, includeValues); // Calculate pads middle = Math.Max(Math.Max(padValue, nodeLabel.Length), rightPosition + leftWidth - leftPosition + 1); position_out = leftPosition + middle; width_out = leftPosition + middle + rightWidth - rightPosition; while (leftLines.Count < rightLines.Count) { leftLines.Add(new string(' ', leftWidth)); } while (rightLines.Count < leftLines.Count) { rightLines.Add(new string(' ', rightWidth)); } if ((middle - nodeLabel.Length % padValue == 1) && (nodeLabel.Length < middle) && node.Parent != null && node.IsLeftChild) { nodeLabel += "."; } // Format the node's label nodeLabel = nodeLabel.PadCenter(middle, '.'); var nodeLabelChars = nodeLabel.ToCharArray(); if (nodeLabelChars[0] == '.') { nodeLabelChars[0] = ' '; } if (nodeLabelChars[nodeLabelChars.Length - 1] == '.') { nodeLabelChars[nodeLabelChars.Length - 1] = ' '; } nodeLabel = string.Join("", nodeLabelChars); // // Construct the list of lines. listOfLines = new List <string> { // 0 new string(' ', leftPosition) + nodeLabel + new string(' ', rightWidth - rightPosition), // 1 new string(' ', leftPosition) + "/" + new string(' ', middle - padValue) + "\\" + new string(' ', rightWidth - rightPosition) }; // // Add the right lines and left lines to the final list of lines. listOfLines = listOfLines.Concat( leftLines.Zip( rightLines, (left_line, right_line) => left_line + new string(' ', width_out - leftWidth - rightWidth) + right_line) ).ToList(); // // Return widthOutput = width_out; positionOutput = position_out; return(listOfLines); }
public void Reset() { current = null; }
public void Dispose() { current = null; tree = null; }
/// <summary> /// CONSTRUCTOR. /// If allowDuplictes is set to false, no duplicate items will be inserted. /// </summary> public BinarySearchTreeMap(bool allowDuplicates) { _count = 0; _allowDuplicates = allowDuplicates; Root = null; }
/// <summary> /// CONSTRUCTOR. /// Allows duplicates by default. /// </summary> public BinarySearchTreeMap() { _count = 0; _allowDuplicates = true; Root = null; }