private void rotateRight(Node<K, V> root) { int i; int i2 = 0; Node<K, V> pivot = root.left; Node<K, V> right = root.right; Node<K, V> pivotLeft = pivot.left; Node<K, V> pivotRight = pivot.right; root.left = pivotRight; if (pivotRight != null) { pivotRight.parent = root; } replaceInParent(root, pivot); pivot.right = root; root.parent = pivot; if (right != null) { i = right.height; } else { i = 0; } root.height = Math.max(i, pivotRight != null ? pivotRight.height : 0) + 1; int i3 = root.height; if (pivotLeft != null) { i2 = pivotLeft.height; } pivot.height = Math.max(i3, i2) + 1; }
private void rebalance(Node<K, V> unbalanced, boolean insert) { for (Node<K, V> node = unbalanced; node != null; node = node.parent) { Node<K, V> left = node.left; Node<K, V> right = node.right; int leftHeight = left != null ? left.height : 0; int rightHeight = right != null ? right.height : 0; int delta = leftHeight - rightHeight; if (delta == -2) { Node<K, V> rightLeft = right.left; Node<K, V> rightRight = right.right; int rightDelta = (rightLeft != null ? rightLeft.height : 0) - (rightRight != null ? rightRight.height : 0); if (rightDelta == -1 || (rightDelta == 0 && !insert)) { rotateLeft(node); } else if ($assertionsDisabled || rightDelta == 1) { rotateRight(right); rotateLeft(node); } else { throw new AssertionError(); } if (insert) { return; } } else if (delta == 2) { Node<K, V> leftLeft = left.left; Node<K, V> leftRight = left.right; int leftDelta = (leftLeft != null ? leftLeft.height : 0) - (leftRight != null ? leftRight.height : 0); if (leftDelta == 1 || (leftDelta == 0 && !insert)) { rotateRight(node); } else if ($assertionsDisabled || leftDelta == -1) { rotateLeft(left); rotateRight(node); } else { throw new AssertionError(); } if (insert) { return; } } else if (delta == 0) { node.height = leftHeight + 1; if (insert) { return; } } else if ($assertionsDisabled || delta == -1 || delta == 1) { node.height = Math.max(leftHeight, rightHeight) + 1; if (!insert) { return; } } else { throw new AssertionError(); } } }
private Node<T, V> insertTree(Node<T, V> subTree, T t, V v) // called by public void insert(T t) { // insert to a subtree and return the reference of this subtree Node<T, V> ansNode = null; if (subTree == null) { ansNode = new Node<T, V>(t, v); ansNode.leftChild = null; ansNode.rightChild = null; ansNode.height = 0; // null tree's height is -1 } else if (comp.compare(t, subTree.t) < 0) // insert to the leftSubTree of subTree { subTree.leftChild = insertTree(subTree.leftChild, t, v); if (getHeight(subTree.leftChild) - getHeight(subTree.rightChild) == 2) // subtree is the minimum unbalanced subTree { // singleLeftRotate or doubleLeftRightRorate if (getHeight(subTree.leftChild.leftChild) > getHeight(subTree.leftChild.rightChild)) { ansNode = singleLeftRotate(subTree); } else { ansNode = doubleLeftRightRotate(subTree); } } else { // Only the change of structure of tree causes the change of it's height subTree.height = 1 + (getHeight(subTree.leftChild) >= getHeight(subTree.rightChild) ? getHeight(subTree.leftChild) : getHeight(subTree.rightChild)); ansNode = subTree; } } else if (comp.compare(t, subTree.t) > 0) // insert to the rightSubTree of subTree { subTree.rightChild = insertTree(subTree.rightChild, t, v); if (getHeight(subTree.rightChild) - getHeight(subTree.leftChild) == 2) // subtree is the minimum unbalanced subTree { // singleLeftRotate or doubleLeftRightRorate if (getHeight(subTree.rightChild.rightChild) > getHeight(subTree.rightChild.leftChild)) { ansNode = singleRightRotate(subTree); } else { ansNode = doubleRightLeftRotate(subTree); } } else { // Only the change of structure of tree causes the change of it's height subTree.height = 1 + (getHeight(subTree.leftChild) > getHeight(subTree.rightChild) ? getHeight(subTree.leftChild) : getHeight(subTree.rightChild)); ansNode = subTree; } } return ansNode; }
private int height() { int h = 1; if (left == null && right == null) { return h; } else if (left == null && right != null) { h += right.height(); } else if (left != null && right == null) { h += left.height(); } else { h += Math.max(left.height(), right.height()); } return h; }
public int leftHeight() { if (left == null) { return 0; } else { return left.height(); } }
public int rightHeight() { if (right == null) { return 0; } else { return right.height(); } }
private Node delete(Node x, Key key) { if (x == null) return null; int comp = key.compareTo(x.key); if (comp < 0) x.left = delete(x.left, key); else if (comp > 0) x.right = delete(x.right, key); else { if (x.left == null) { if (x.pred != null) x.pred.succ = x.succ; if (x.succ != null) x.succ.pred = x.pred; return x.right; } if (x.right == null) { if (x.pred != null) x.pred.succ = x.succ; if (x.succ != null) x.succ.pred = x.pred; return x.left; } Node t = max(x.left); t.left = deleteMaxWithOutDeleteThread(x.left); t.right = x.right; if (x.pred != null) x.pred.succ = x.succ; if (x.succ != null) x.succ.pred = x.pred; x = t; } x.N = size(x.left) + size(x.right) + 1; x.height = Math.max(height(x.left), height(x.right)) + 1; x.avgCompares = (avgCompares(x.left) * size(x.left) + avgCompares(x.right) * size(x.right) + size(x)) / size(x); return x; }
private Node put(Node x, Key key, Value val) { if (x == null) { Node pre = floor(root, key); Node nex = ceiling(root, key); lastest = new Node(key, val, 1, 1, 1); if (pre != null) pre.succ = lastest; if (nex != null) nex.pred = lastest; lastest.succ = nex; lastest.pred = pre; return lastest; } int comp = key.compareTo(x.key); if (comp < 0) x.left = put(x.left, key, val); else if (comp > 0) x.right = put(x.right, key, val); else { lastest = x; x.value = val; } x.N = size(x.right) + size(x.left) + 1; x.height = Math.max(height(x.left), height(x.right)) + 1; x.avgCompares = (avgCompares(x.left) * size(x.left) + avgCompares(x.right) * size(x.right) + size(x)) / size(x); return x; }
// OUTER methods here are wrapper methods for the root public int getHeight() { if (root == null) { return 0; } else { return root.height(); } }
/** * ********************************* rotation operation * ****************************************************** */ private Node<T, V> singleLeftRotate(Node<T, V> subTree) { // rotate Node<T, V> ansNode = subTree.leftChild; subTree.leftChild = ansNode.rightChild; ansNode.rightChild = subTree; // update height of rotated nodes // Only the change of structure of tree causes the change of it's height subTree.height = 1 + (getHeight(subTree.leftChild) >= getHeight(subTree.rightChild) ? getHeight(subTree.leftChild) : getHeight(subTree.rightChild)); ansNode.height = 1 + (getHeight(ansNode.leftChild) >= getHeight(ansNode.rightChild) ? getHeight(ansNode.leftChild) : getHeight(ansNode.rightChild)); return ansNode; }
private Node deleteMaxWithOutDeleteThread(Node x) { if (x == null) return null; if (x.right == null) { return x.left; } x.right = deleteMax(x.right); x.N = size(x.left) + size(x.right) + 1; x.height = Math.max(height(x.left), height(x.right)) + 1; x.avgCompares = (avgCompares(x.left) * size(x.left) + avgCompares(x.right) * size(x.right) + size(x)) / size(x); return x; }
private void computeSize(Array<Node> nodes, float indent) { float ySpacing = this.ySpacing; for (int i = 0, n = nodes.size; i < n; i++) { Node node = nodes.get(i); float rowWidth = indent + iconSpacing; Actor actor = node.actor; if (actor instanceof Layout) { Layout layout = (Layout) actor; rowWidth += layout.getPrefWidth(); node.height = layout.getPrefHeight(); layout.pack(); } else { rowWidth += actor.getWidth(); node.height = actor.getHeight(); } if (node.icon != null) { rowWidth += iconSpacing * 2 + node.icon.getMinWidth(); node.height = Math.max(node.height, node.icon.getMinHeight()); } prefWidth = Math.max(prefWidth, rowWidth); prefHeight -= node.height + ySpacing; if (node.expanded) computeSize(node.children, indent + indentSpacing); } }
private Node deleteMax(Node x) { if (x == null) return null; if (x.right == null) { if (x.pred != null) x.pred.succ = x.succ; if (x.succ != null) x.succ.pred = x.pred; return x.left; } x.right = deleteMax(x.right); x.N = size(x.left) + size(x.right) + 1; x.height = Math.max(height(x.left), height(x.right)) + 1; x.avgCompares = (avgCompares(x.left) * size(x.left) + avgCompares(x.right) * size(x.right) + size(x)) / size(x); return x; }
void removeInternal(Node<K, V> node, boolean unlink) { if (unlink) { node.prev.next = node.next; node.next.prev = node.prev; } Node<K, V> left = node.left; Node<K, V> right = node.right; Node<K, V> originalParent = node.parent; if (left == null || right == null) { if (left != null) { replaceInParent(node, left); node.left = null; } else if (right != null) { replaceInParent(node, right); node.right = null; } else { replaceInParent(node, null); } rebalance(originalParent, false); this.size--; this.modCount++; return; } Node<K, V> adjacent = left.height > right.height ? left.last() : right.first(); removeInternal(adjacent, false); int leftHeight = 0; left = node.left; if (left != null) { leftHeight = left.height; adjacent.left = left; left.parent = adjacent; node.left = null; } int rightHeight = 0; right = node.right; if (right != null) { rightHeight = right.height; adjacent.right = right; right.parent = adjacent; node.right = null; } adjacent.height = Math.max(leftHeight, rightHeight) + 1; replaceInParent(node, adjacent); }
private Node<T, V> deleteTree(T delT, Node<T, V> subTree) { Node<T, V> ansNode = null; if (subTree == null) { System.err.println(delT + "doesn't exist."); System.err.flush(); ansNode = subTree; } else if (comp.compare(delT, subTree.t) < 0) // delT maybe in the leftSubTree of subTree { subTree.leftChild = deleteTree(delT, subTree.leftChild); // the height of leftSubTree of subTree may decrease // once leftSubTree was return, it is balanced if (getHeight(subTree.rightChild) - getHeight(subTree.leftChild) >= 2) // subtree is the minimum unbalanced subTree { // singleRightRotate or doubleRightLeftRorate if (getHeight(subTree.rightChild.rightChild) >= getHeight(subTree.rightChild.leftChild)) { ansNode = singleRightRotate(subTree); } else { ansNode = doubleRightLeftRotate(subTree); } } else // subTree is balanced, but need to update its height { // Only the change of structure of tree causes the change of it's height subTree.height = 1 + (getHeight(subTree.leftChild) >= getHeight(subTree.rightChild) ? getHeight(subTree.leftChild) : getHeight(subTree.rightChild)); ansNode = subTree; } } else if (comp.compare(delT, subTree.t) > 0) // delT maybe in the rightSubTree of subTree { subTree.rightChild = deleteTree( delT, subTree.rightChild); // the height of rightSubTree of subTree may decrease // once rightSubTree was return, it is balanced if (getHeight(subTree.leftChild) - getHeight(subTree.rightChild) >= 2) // subtree is the minimum unbalanced subTree { // singleLeftRotate or doubleLeftRightRotate if (getHeight(subTree.leftChild.leftChild) >= getHeight(subTree.leftChild.rightChild)) { ansNode = singleLeftRotate(subTree); } else { ansNode = doubleLeftRightRotate(subTree); } } else { // Only the change of structure of tree causes the change of it's height subTree.height = 1 + (getHeight(subTree.leftChild) >= getHeight(subTree.rightChild) ? getHeight(subTree.leftChild) : getHeight(subTree.rightChild)); ansNode = subTree; } } else if (comp.compare(delT, subTree.t) == 0) { if (subTree.leftChild == null && subTree.rightChild == null) { ansNode = null; // once null is returned, subTree will be recycled anytime } else if (subTree.leftChild != null && subTree.rightChild != null) { subTree.t = getMin(subTree.rightChild).t; subTree.v = getMin(subTree.rightChild).v; subTree.rightChild = deleteTree( subTree.t, subTree.rightChild); // the height of rightSubTree of subTree may decrease // once rightSubTree was return, it is balanced if (getHeight(subTree.leftChild) - getHeight(subTree.rightChild) >= 2) // subtree is the minimum unbalanced subTree { // singleLeftRotate or doubleLeftRightRotate if (getHeight(subTree.leftChild.leftChild) >= getHeight(subTree.leftChild.rightChild)) { ansNode = singleLeftRotate(subTree); } else { ansNode = doubleLeftRightRotate(subTree); } } else { // Only the change of structure of tree causes the change of it's height subTree.height = 1 + (getHeight(subTree.leftChild) >= getHeight(subTree.rightChild) ? getHeight(subTree.leftChild) : getHeight(subTree.rightChild)); ansNode = subTree; } } else { if (subTree.leftChild != null && subTree.rightChild == null) { ansNode = subTree.leftChild; // once returned, subTree will be recycled anytime subTree.leftChild = null; } else if (subTree.leftChild == null && subTree.rightChild != null) { ansNode = subTree.rightChild; subTree.rightChild = null; } } } return ansNode; }
// methods to reset and get the height of a node private void resetHeight(Node n) { n.height = Math.max(getHeight(n.left), getHeight(n.right)) + 1; }