Example #1
0
        /// <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);
        }
Example #2
0
 /// <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));
     }
 }
Example #3
0
        /// <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));
                    }
                }
            }
        }
Example #4
0
        /// <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));
        }
Example #7
0
 private void visitNode(BSTMapNode <TKey, TValue> node)
 {
     if (node == null)
     {
         return;
     }
     visitNode(node.LeftChild);
     visitNode(node.RightChild);
     traverseQueue.Enqueue(node);
 }
Example #8
0
        /// <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.");
            }
        }
Example #9
0
            public bool MoveNext()
            {
                if (traverseQueue.Count > 0)
                {
                    current = traverseQueue.Dequeue();
                }
                else
                {
                    current = null;
                }

                return(current != null);
            }
Example #10
0
        /// <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);
        }
Example #11
0
        /// <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);
        }
Example #12
0
        /// <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);
        }
Example #13
0
        /// <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;
            }
        }
Example #14
0
        /// <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);
        }
Example #15
0
        /// <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));
 }
Example #17
0
        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);
        }
Example #18
0
 public void Reset()
 {
     current = null;
 }
Example #19
0
 public void Dispose()
 {
     current = null;
     tree    = null;
 }
Example #20
0
 /// <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;
 }
Example #21
0
 /// <summary>
 /// CONSTRUCTOR.
 /// Allows duplicates by default.
 /// </summary>
 public BinarySearchTreeMap()
 {
     _count           = 0;
     _allowDuplicates = true;
     Root             = null;
 }