//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); } } } }
/// <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)); }
private int getHeight(TreapTreeNode <T> node) { if (node == null) { return(-1); } return(Math.Max(getHeight(node.Left), getHeight(node.Right)) + 1); }
private TreapTreeNode <T> findMax(TreapTreeNode <T> node) { while (true) { if (node.Right == null) { return(node); } node = node.Right; } }
private TreapTreeNode <T> findMin(TreapTreeNode <T> node) { while (true) { if (node.Left == null) { return(node); } node = node.Left; } }
/// <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); }
//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; } } }
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; } }
/// <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); }
/// <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); }
//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"); } }
//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; } }
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); }
internal TreapTreeNode(TreapTreeNode <T> parent, T value, int priority) { Parent = parent; Value = value; Priority = priority; }
internal TreapTreeNode(TreapTreeNode <T> parent, T value, int priority) { this.Parent = parent; this.Value = value; this.Priority = priority; }