//find the node with the given identifier among descendants of parent and parent
        //uses pre-order traversal
        //O(log(n)) worst O(n) for unbalanced tree
        private TreapTreeNode <T> Find(TreapTreeNode <T> parent, T value)
        {
            if (parent == null)
            {
                return(null);
            }

            if (parent.Value.CompareTo(value) == 0)
            {
                return(parent);
            }

            var left = Find(parent.Left, value);

            if (left != null)
            {
                return(left);
            }

            var right = Find(parent.Right, value);

            if (right != null)
            {
                return(right);
            }

            return(null);
        }
        private void deleteLeftNode(TreapTreeNode <T> node)
        {
            //root
            if (node.Parent == null)
            {
                Root.Left.Parent = null;
                Root             = Root.Left;
                return;
            }
            else
            {
                //node is left child of parent
                if (node.IsLeftChild)
                {
                    node.Parent.Left = node.Left;
                }
                //node is right child of parent
                else
                {
                    node.Parent.Right = node.Left;
                }

                node.Left.Parent = node.Parent;
            }
        }
        //O(log(n)) worst O(n) for unbalanced tree
        private void delete(TreapTreeNode <T> node, T value)
        {
            var compareResult = node.Value.CompareTo(value);

            //node is less than the search value so move right to find the deletion node
            if (compareResult < 0)
            {
                if (node.Right == null)
                {
                    throw new Exception("Item do not exist");
                }

                delete(node.Right, value);
            }
            //node is less than the search value so move left to find the deletion node
            else if (compareResult > 0)
            {
                if (node.Left == null)
                {
                    throw new Exception("Item do not exist");
                }

                delete(node.Left, value);
            }
            else
            {
                var parent = node.Parent;
                //node is a leaf node
                if (node.IsLeaf)
                {
                    deleteLeaf(node);
                }
                else
                {
                    //case one - right tree is null (move sub tree up)
                    if (node.Left != null && node.Right == null)
                    {
                        deleteLeftNode(node);
                    }
                    //case two - left tree is null  (move sub tree up)
                    else if (node.Right != null && node.Left == null)
                    {
                        deleteRightNode(node);
                    }
                    //case three - two child trees
                    //replace the node value with maximum element of left subtree (left max node)
                    //and then delete the left max node
                    else
                    {
                        var maxLeftNode = FindMax(node.Left);

                        node.Value = maxLeftNode.Value;

                        //delete left max node
                        delete(node.Left, maxLeftNode.Value);
                    }
                }
            }
        }
示例#4
0
 /// <summary>
 /// Initialize the BST with given sorted keys.
 /// Time complexity: O(n).
 /// </summary>
 /// <param name="sortedCollection">The initial sorted collection.</param>
 public TreapTree(IEnumerable <T> sortedCollection, IComparer <T> comparer = null) : this(comparer)
 {
     BSTHelpers.ValidateSortedCollection(sortedCollection, this.comparer);
     var nodes = sortedCollection.Select(x => new TreapTreeNode <T>(null, x, rndGenerator.Next())).ToArray();
     Root = (TreapTreeNode <T>)BSTHelpers.ToBST(nodes);
     BSTHelpers.AssignCount(Root);
     heapify(Root);
 }
        /// <summary>
        /// Initialize the BST with given sorted keys.
        /// Time complexity: O(n).
        /// </summary>
        /// <param name="sortedKeys">The sorted keys.</param>
        public TreapTree(IEnumerable <T> collection) : this()
        {
            ValidateCollection(collection);
            var nodes = collection.Select(x => new TreapTreeNode <T>(null, x, rndGenerator.Next())).ToArray();

            Root = (TreapTreeNode <T>)ToBST(nodes);
            assignCount(Root);
            heapify(Root);
        }
        private TreapTreeNode <T> FindMin(TreapTreeNode <T> node)
        {
            if (node.Left == null)
            {
                return(node);
            }

            return(FindMin(node.Left));
        }
        private TreapTreeNode <T> FindMax(TreapTreeNode <T> node)
        {
            if (node.Right == null)
            {
                return(node);
            }

            return(FindMax(node.Right));
        }
示例#8
0
        private int getHeight(TreapTreeNode <T> node)
        {
            if (node == null)
            {
                return(-1);
            }

            return(Math.Max(getHeight(node.Left), getHeight(node.Right)) + 1);
        }
示例#9
0
 private TreapTreeNode <T> findMax(TreapTreeNode <T> node)
 {
     while (true)
     {
         if (node.Right == null)
         {
             return(node);
         }
         node = node.Right;
     }
 }
示例#10
0
        private TreapTreeNode <T> findMin(TreapTreeNode <T> node)
        {
            while (true)
            {
                if (node.Left == null)
                {
                    return(node);
                }

                node = node.Left;
            }
        }
示例#11
0
        /// <summary>
        /// Time complexity: O(log(n))
        /// </summary>
        public void Insert(T value)
        {
            if (Root == null)
            {
                Root = new TreapTreeNode <T>(null, value, rndGenerator.Next());
                return;
            }

            var newNode = insert(Root, value);

            heapify(newNode);
        }
示例#12
0
 //reorder the tree node so that heap property is valid
 private void heapify(TreapTreeNode <T> node)
 {
     while (node.Parent != null)
     {
         if (node.Priority < node.Parent.Priority)
         {
             node = node.IsLeftChild ? rightRotate(node.Parent) : leftRotate(node.Parent);
         }
         else
         {
             break;
         }
     }
 }
示例#13
0
 private void deleteLeaf(TreapTreeNode <T> node)
 {
     //if node is root
     if (node.Parent == null)
     {
         Root = null;
     }
     //assign nodes parent.left/right to null
     else if (node.IsLeftChild)
     {
         node.Parent.Left = null;
     }
     else
     {
         node.Parent.Right = null;
     }
 }
示例#14
0
        /// <summary>
        /// Rotates the current root left and returns new root
        /// </summary>
        private TreapTreeNode <T> leftRotate(TreapTreeNode <T> currentRoot)
        {
            var prevRoot       = currentRoot;
            var rightLeftChild = prevRoot.Right.Left;

            var newRoot = currentRoot.Right;

            //make right child as root
            prevRoot.Right.Parent = prevRoot.Parent;

            if (prevRoot.Parent != null)
            {
                if (prevRoot.Parent.Left == prevRoot)
                {
                    prevRoot.Parent.Left = prevRoot.Right;
                }
                else
                {
                    prevRoot.Parent.Right = prevRoot.Right;
                }
            }


            //move prev root as left child of current root
            newRoot.Left    = prevRoot;
            prevRoot.Parent = newRoot;

            //move left child of right child of prev root to right child of left child of new root
            newRoot.Left.Right = rightLeftChild;
            if (newRoot.Left.Right != null)
            {
                newRoot.Left.Right.Parent = newRoot.Left;
            }

            newRoot.Left.UpdateCounts();
            newRoot.Right.UpdateCounts();
            newRoot.UpdateCounts();

            if (prevRoot == Root)
            {
                Root = newRoot;
            }

            return(newRoot);
        }
示例#15
0
        /// <summary>
        /// Rotates current root right and returns the new root node
        /// </summary>
        /// <param name="currentRoot"></param>
        /// <returns></returns>
        private TreapTreeNode <T> RightRotate(TreapTreeNode <T> currentRoot)
        {
            var prevRoot       = currentRoot;
            var leftRightChild = prevRoot.Left.Right;

            var newRoot = currentRoot.Left;

            //make left child as root
            prevRoot.Left.Parent = prevRoot.Parent;

            if (prevRoot.Parent != null)
            {
                if (prevRoot.Parent.Left == prevRoot)
                {
                    prevRoot.Parent.Left = prevRoot.Left;
                }
                else
                {
                    prevRoot.Parent.Right = prevRoot.Left;
                }
            }

            //move prev root as right child of current root
            newRoot.Right   = prevRoot;
            prevRoot.Parent = newRoot;

            //move right child of left child of prev root to left child of right child of new root
            newRoot.Right.Left = leftRightChild;
            if (newRoot.Right.Left != null)
            {
                newRoot.Right.Left.Parent = newRoot.Right;
            }

            if (prevRoot == Root)
            {
                Root = newRoot;
            }

            return(newRoot);
        }
示例#16
0
        //O(log(n)) always
        private TreapTreeNode <T> insert(
            TreapTreeNode <T> currentNode, T newNodeValue)
        {
            var compareResult = currentNode.Value.CompareTo(newNodeValue);

            //current node is less than new item
            if (compareResult < 0)
            {
                //no right child
                if (currentNode.Right == null)
                {
                    //insert
                    currentNode.Right = new TreapTreeNode <T>(currentNode, newNodeValue, rndGenerator.Next());
                    return(currentNode.Right);
                }
                else
                {
                    return(insert(currentNode.Right, newNodeValue));
                }
            }
            //current node is greater than new node
            else if (compareResult > 0)
            {
                if (currentNode.Left == null)
                {
                    //insert
                    currentNode.Left = new TreapTreeNode <T>(currentNode, newNodeValue, rndGenerator.Next());
                    return(currentNode.Left);
                }
                else
                {
                    return(insert(currentNode.Left, newNodeValue));
                }
            }
            else
            {
                throw new Exception("Item exists");
            }
        }
示例#17
0
        //find the node with the given identifier among descendants of parent and parent
        //uses pre-order traversal
        private TreapTreeNode <T> find(TreapTreeNode <T> parent, T value)
        {
            while (true)
            {
                if (parent == null)
                {
                    return(null);
                }

                if (comparer.Compare(parent.Value, value) == 0)
                {
                    return(parent);
                }

                var left = find(parent.Left, value);

                if (left != null)
                {
                    return(left);
                }

                parent = parent.Right;
            }
        }
示例#18
0
        private void delete(TreapTreeNode <T> node, T value)
        {
            while (true)
            {
                if (node != null)
                {
                    var compareResult = comparer.Compare(node.Value, value);

                    //node is less than the search value so move right to find the deletion node
                    if (compareResult < 0)
                    {
                        node = node.Right ?? throw new Exception("Item do not exist");
                        continue;
                    }
                    //node is less than the search value so move left to find the deletion node

                    if (compareResult > 0)
                    {
                        node = node.Left ?? throw new Exception("Item do not exist");
                        continue;
                    }
                }

                //node is a leaf node
                if (node != null && node.IsLeaf)
                {
                    deleteLeaf(node);
                }
                else
                {
                    //case one - right tree is null (move sub tree up)
                    if (node?.Left != null && node.Right == null)
                    {
                        deleteLeftNode(node);
                    }
                    //case two - left tree is null  (move sub tree up)
                    else if (node?.Right != null && node.Left == null)
                    {
                        deleteRightNode(node);
                    }
                    //case three - two child trees
                    //replace the node value with maximum element of left subtree (left max node)
                    //and then delete the left max node
                    else
                    {
                        if (node != null)
                        {
                            var maxLeftNode = findMax(node.Left);

                            node.Value = maxLeftNode.Value;

                            //delete left max node
                            node  = node.Left;
                            value = maxLeftNode.Value;
                        }

                        continue;
                    }
                }

                break;
            }

            node.UpdateCounts(true);
        }
示例#19
0
 internal TreapTreeNode(TreapTreeNode <T> parent, T value, int priority)
 {
     Parent   = parent;
     Value    = value;
     Priority = priority;
 }
示例#20
0
 internal TreapTreeNode(TreapTreeNode <T> parent, T value, int priority)
 {
     this.Parent   = parent;
     this.Value    = value;
     this.Priority = priority;
 }