Example #1
0
 /// <summary>
 ///     Adds a new node to the tree
 /// </summary>
 /// <param name="key">The node key</param>
 /// <param name="value">The node data value</param>
 /// <returns>Returns TRUE if a new node was added; returns FALSE if a node with the same key was found</returns>
 public bool Add(TKey key, TValue value)
 {
     return(BinarySearchTreeNode <TKey, TValue> .Add(ref m_root, key, value, m_cmp));
 }
Example #2
0
 /// <summary>
 ///     Removes a node from the tree
 /// </summary>
 /// <param name="key">The node key</param>
 /// <returns>Returns TRUE if a node was removed; returns FALSE if a node with the same key was not found</returns>
 public bool Remove(TKey key)
 {
     return(BinarySearchTreeNode <TKey, TValue> .Remove(ref m_root, key, m_cmp));
 }
Example #3
0
        /// <summary>
        ///     Removes a node from the tree
        /// </summary>
        /// <param name="tree">The tree to remove a node</param>
        /// <param name="key">The node key</param>
        /// <param name="comparer">The key comparer</param>
        /// <returns>Returns TRUE if a node was removed; returns FALSE if a node with the same key was not found</returns>
        public static bool Remove(ref BinarySearchTreeNode <TKey, TValue> tree, TKey key, IComparer <TKey> comparer = null)
        {
            if (tree == null)
            {
                throw new ArgumentNullException(nameof(tree));
            }
            if (key == null)
            {
                throw new ArgumentNullException(nameof(key));
            }
            var cmp     = comparer ?? Comparer <TKey> .Default;
            var current = tree;
            var parent  = (BinarySearchTreeNode <TKey, TValue>)null;
            int c;

            // trace down the tree until we hit a NULL
            while (current != null)
            {
                c = cmp.Compare(key, current.Value.Key);
                if (c == 0)
                {
                    break;
                }
                parent = current;
                if (c < 0)
                {
                    // current.Value.Key > key, search current's left subtree
                    current = current.Left;
                }
                else
                {
                    // current.Value.Key < key, search current's right subtree
                    current = current.Right;
                }
            }
            if (current == null)
            {
                // a node with the key was not found
                return(false);
            }
            // if current has no right child, then current's left child becomes the node pointed to by the parent
            if (current.Right == null)
            {
                if (parent == null)
                {
                    tree = current.Left;
                }
                else
                {
                    c = cmp.Compare(parent.Value.Key, current.Value.Key);
                    if (c > 0)
                    {
                        // parent.Value.Key > current.Value.Key, so make current's left child a left child of parent
                        parent.Left = current.Left;
                    }
                    else
                    {
                        // parent.Value.Key < current.Value.Key, so make current's left child a right child of parent
                        parent.Right = current.Left;
                    }
                }
            }
            // if current's right child has no left child, then current's right child replaces current in the tree
            else if (current.Right.Left == null)
            {
                current.Right.Left = current.Left;
                if (parent == null)
                {
                    tree = current.Right;
                }
                else
                {
                    c = cmp.Compare(parent.Value.Key, current.Value.Key);
                    if (c > 0)
                    {
                        // parent.Value > current.Value, so make current's right child a left child of parent
                        parent.Left = current.Right;
                    }
                    else if (c < 0)
                    {
                        // parent.Value < current.Value, so make current's right child a right child of parent
                        parent.Right = current.Right;
                    }
                }
            }
            // if current's right child has a left child, replace current with current's right child's left-most descendent
            else
            {
                // We first need to find the right node's left-most child
                var leftMost       = current.Right.Left;
                var leftMostParent = current.Right;
                while (leftMost.Left != null)
                {
                    leftMostParent = leftMost;
                    leftMost       = leftMost.Left;
                }

                // the parent's left subtree becomes the leftMost's right subtree
                leftMostParent.Left = leftMost.Right;

                // assign leftmost's left and right to current's left and right children
                leftMost.Left  = current.Left;
                leftMost.Right = current.Right;

                if (parent == null)
                {
                    tree = leftMost;
                }
                else
                {
                    c = cmp.Compare(parent.Value.Key, current.Value.Key);
                    if (c > 0)
                    {
                        // parent.Value > current.Value, so make leftmost a left child of parent
                        parent.Left = leftMost;
                    }
                    else if (c < 0)
                    {
                        // parent.Value < current.Value, so make leftmost a right child of parent
                        parent.Right = leftMost;
                    }
                }
            }
            // a node with the key was removed
            return(true);
        }