internal void CheckRoom(QueuedAVLTree <TKey, TValue> tree) { if (size + 1 > maxSize) { Dequeue(last.previous, tree, true); } }
internal static void Remove(QueueElement element, QueuedAVLTree <TKey, TValue> tree, bool callFromQueue = false) { element.next.previous = element.previous; element.previous.next = element.next; if (callFromQueue && element.linkedNode != null) { AVLNode.RemoveNode(element.linkedNode, tree, true); } }
internal QueueElement Enqueue(AVLNode node, QueuedAVLTree <TKey, TValue> tree) { if (size > maxSize) { Dequeue(last.previous, tree, true); } QueueElement element = new QueueElement(first, node); size++; return(element); }
private static void RotateRight(AVLNode node, QueuedAVLTree <TKey, TValue> tree) { // swap head AVLNode oldhead = node.head; node.head = node.head.head; oldhead.head = node; // change, who is r,l (also isLeft) bool tmpb = node.isLeft; node.isLeft = oldhead.isLeft; oldhead.isLeft = false; if (node.head != null) { if (node.isLeft) { node.head.left = node; } else { node.head.right = node; } } else { tree.head = node; node.head = null; } // update children oldhead.left = node.right; node.right = oldhead; if (oldhead.left != null) { oldhead.left.isLeft = true; oldhead.left.head = oldhead; } oldhead.isLeft = false; // update balances UpdateDepth(oldhead); UpdateDepth(node); }
/// <summary> /// Called after removing a node - can handle more than 2 or -2 balances on self /// </summary> internal static void BalanceSelfBubbleUp(AVLNode node, QueuedAVLTree <TKey, TValue> tree) { while (node != null) { node._depthL = node.left == null ? 0 : (GetMaxDepth(node.left) + 1); node._depthR = node.right == null ? 0 : (GetMaxDepth(node.right) + 1); if (Math.Abs(node.balance) > 1) { node.Rebalance(tree); } else { node = node.head; } } }
internal static bool FindRemoveItem(AVLNode node, QueuedAVLTree <TKey, TValue> tree, KeyValuePair <TKey, TValue> item, ref int elementCount) { int compare = item.Key.CompareTo(node.key); while (true) { if (compare < 0) { node = node.left; if (node != null) { compare = item.Key.CompareTo(node.key); } else { return(false); } } else if (compare > 0) { node = node.right; if (node != null) { compare = item.Key.CompareTo(node.key); } else { return(false); } } else { if (node.value.Equals(item.Value)) { AVLNode.RemoveNode(node, tree); return(true); } return(false); } } }
internal static bool FindRemoveKey(AVLNode node, QueuedAVLTree <TKey, TValue> tree, TKey key, ref int elementCount) { int compare = key.CompareTo(node.key); while (true) { if (compare < 0) { node = node.left; if (node != null) { compare = key.CompareTo(node.key); } else { return(false); } } else if (compare > 0) { node = node.right; if (node != null) { compare = key.CompareTo(node.key); } else { return(false); } } else { AVLNode.RemoveNode(node, tree); return(true); } } }
/// <summary> /// Called after adding a node /// </summary> internal static void BalanceBubbleUp(AVLNode node, QueuedAVLTree <TKey, TValue> tree) { while (node.head != null) { if (node._depthL > node._depthR) { if (node.isLeft) { node.head._depthL = node._depthL + 1; } else { node.head._depthR = node._depthL + 1; } } else { if (node.isLeft) { node.head._depthL = node._depthR + 1; } else { node.head._depthR = node._depthR + 1; } } if (Math.Abs(node.head.balance) > 1) { node.head.Rebalance(tree); } else { node = node.head; } } }
internal static void AddItem(TKey key, TValue value, QueuedAVLTree <TKey, TValue> tree, ref int elementCount) { if (!tree.ContainsKey(key)) { tree.queue.CheckRoom(tree); if (tree.head == null) { tree.head = new AVLNode(key, value, tree); elementCount++; goto LukeIDeletedYourFather; } } AVLNode headNode = tree.head; int compare = key.CompareTo(headNode.key); while (true) { if (compare < 0) { if (headNode.left == null) { headNode.left = new AVLNode(key: key, value: value, tree: tree) { head = headNode, isLeft = true }; headNode._depthL = 1; AVLNode.BalanceBubbleUp(headNode, tree); elementCount++; break; } else { headNode = headNode.left; compare = key.CompareTo(headNode.key); } } else if (compare > 0) { if (headNode.right == null) { headNode.right = new AVLNode(key: key, value: value, tree: tree) { head = headNode, isLeft = false }; headNode._depthR = 1; AVLNode.BalanceBubbleUp(headNode, tree); elementCount++; break; } else { headNode = headNode.right; compare = key.CompareTo(headNode.key); } } else { headNode.value = value; break; } } LukeIDeletedYourFather :; }
internal static void RemoveNode(AVLNode node, QueuedAVLTree <TKey, TValue> tree, bool callFromQueue = false) { if (!callFromQueue) { tree.queue.Dequeue(node.linkedElement, tree); } if (node.right == null && node.left == null) // no children { if (node.head == null) // was the top node { tree.head = null; } else { if (node.isLeft) { node.head.left = null; node.head._depthL = 0; } else { node.head.right = null; node.head._depthR = 0; } AVLNode.BalanceSelfBubbleUp(node.head, tree); } } else if (node.right == null || node.left == null) // one child { AVLNode child = node.right != null ? node.right : node.left; if (node.head == null) // was the top node { tree.head = child; child.head = null; } else { child.isLeft = node.isLeft; if (node.isLeft) { node.head.left = child; child.head = node.head; node.head._depthL -= 1; } else { node.head.right = child; child.head = node.head; node.head._depthR -= 1; } AVLNode.BalanceSelfBubbleUp(node.head, tree); } } else // two children :O { AVLNode child = node.right, childhead = node.head; while (child.left != null) { childhead = child; child = child.left; } if (childhead != node.head) { if (child.right != null) { childhead.left = child.right; child.right.head = childhead; child.right.isLeft = true; childhead._depthL--; } else { childhead.left = null; childhead._depthL = 0; } child.right = node.right; } child.left = node.left; child.left.head = child; child.head = node.head; child.isLeft = node.isLeft; if (node.head == null) { tree.head = child; } else { if (node.isLeft) { node.head.left = child; } else { node.head.right = child; } } if (childhead == node.head) { AVLNode.BalanceSelfBubbleUp(child, tree); } else { child.right.head = child; AVLNode.BalanceSelfBubbleUp(childhead, tree); } } tree.count--; }
private void Rebalance(QueuedAVLTree <TKey, TValue> tree) { if (Math.Abs(balance) > 2) { if (balance < -2) { left.Rebalance(tree); } else { right.Rebalance(tree); } } if (balance > 1) { // 5_2 | 7 // 2 7_1 | 5 8 // 6 8_1 | 2 6 9 // 9 | // 5 | 5 // 2 6 | 3 6 // 3 | 2 4 // 4 | // 5 | 5 | 7 // 2 8 | 2 7 | 5 8 // 7 9 | 6 8 | 2 6 9 // 6 | 9 | if (right.balance > 0) { RotateLeft(right, tree); } else { RotateRight(right.left, tree); RotateLeft(right, tree); } } else if (balance < -1) { // 5 | 5 // 4 9 | 4 8 // 8 | 7 9 // 7 | // 5 | 5 | 3 // 1 6 | 3 6 | 1 5 // 0 3 | 1 4 | 0 4 6 // 4 | 0 | if (left.balance < 0) { RotateRight(left, tree); } else { RotateLeft(left.right, tree); RotateRight(left, tree); } } #if TEST checkNodeSelf(this); #endif }
internal AVLNode(TKey key, TValue value, QueuedAVLTree <TKey, TValue> tree) { this.key = key; this.value = value; this.linkedElement = tree.queue.Enqueue(this, tree); }
internal void Dequeue(QueueElement element, QueuedAVLTree <TKey, TValue> tree, bool callFromEnqueue = false) { QueueElement.Remove(element, tree, callFromEnqueue); size--; }