/** * Return the largest node under <code>node</code>. */ public int last(int node) { while (true) { final int right = right(node); if (right == NIL) { break; } node = right; } return node; }
/** * Return the least node that is strictly greater than <code>node</code>. */ public final int next(int node) { final int right = right(node); if (right != NIL) { return first(right); } else { int parent = parent(node); while (parent != NIL && node == right(parent)) { node = parent; parent = parent(parent); } return parent; } }
/** * Find a node in this tree. */ public int find() { for (int node = root; node != NIL; ) { final int cmp = compare(node); if (cmp < 0) { node = left(node); } else if (cmp > 0) { node = right(node); } else { return node; } } return NIL; }
/** * Return the last node whose centroid is less than <code>centroid</code>. */ @SuppressWarnings("WeakerAccess") public int floor(double centroid) { int floor = IntAVLTree.NIL; for (int node = tree.root(); node != IntAVLTree.NIL; ) { final int cmp = Double.compare(centroid, mean(node)); if (cmp <= 0) { node = tree.left(node); } else { floor = node; node = tree.right(node); } } return floor; }
private int balanceFactor(int node) { return depth(left(node)) - depth(right(node)); }
private void release(int node) { left(node, NIL); right(node, NIL); parent(node, NIL); nodeAllocator.release(node); }
protected void fixAggregates(int node) { depth(node, 1 + Math.max(depth(left(node)), depth(right(node)))); }
/** Rotate left the subtree under <code>n</code> */ private void rotateLeft(int n) { final int r = right(n); final int lr = left(r); right(n, lr); if (lr != NIL) { parent(lr, n); } final int p = parent(n); parent(r, p); if (p == NIL) { root = r; } else if (left(p) == n) { left(p, r); } else { assert right(p) == n; right(p, r); } left(r, n); parent(n, r); fixAggregates(n); fixAggregates(parent(n)); }
/** Rotate right the subtree under <code>n</code> */ private void rotateRight(int n) { final int l = left(n); final int rl = right(l); left(n, rl); if (rl != NIL) { parent(rl, n); } final int p = parent(n); parent(l, p); if (p == NIL) { root = l; } else if (right(p) == n) { right(p, l); } else { assert left(p) == n; left(p, l); } right(l, n); parent(n, l); fixAggregates(n); fixAggregates(parent(n)); }
throw new IllegalArgumentException(); if (left(node) != NIL && right(node) != NIL) { swap(node, next); assert left(node) == NIL || right(node) == NIL; child = right(node); left(parent, NIL); } else { assert node == right(parent); right(parent, NIL); left(parent, child); } else { assert node == right(parent); right(parent, child);
left(parent1, node2); } else { assert node1 == right(parent1); right(parent1, node2); left(parent2, node1); } else { assert node2 == right(parent2); right(parent2, node1); final int right1 = right(node1); final int right2 = right(node2); right(node1, right2); if (right2 != NIL) { parent(right2, node1); right(node2, right1); if (right1 != NIL) { parent(right1, node2);
/** * Compute the number of elements and sum of counts for every entry that * is strictly before <code>node</code>. */ @SuppressWarnings("WeakerAccess") public long headSum(int node) { final int left = tree.left(node); long sum = aggregatedCounts[left]; for (int n = node, p = tree.parent(node); p != IntAVLTree.NIL; n = p, p = tree.parent(n)) { if (n == tree.right(p)) { final int leftP = tree.left(p); sum += counts[p] + aggregatedCounts[leftP]; } } return sum; }
/** * Return the last node so that the sum of counts of nodes that are before * it is less than or equal to <code>sum</code>. */ @SuppressWarnings("WeakerAccess") public int floorSum(long sum) { int floor = IntAVLTree.NIL; for (int node = tree.root(); node != IntAVLTree.NIL; ) { final int left = tree.left(node); final long leftCount = aggregatedCounts[left]; if (leftCount <= sum) { floor = node; sum -= leftCount + count(node); node = tree.right(node); } else { node = tree.left(node); } } return floor; }
private void rebalance(int node) { for (int n = node; n != NIL; ) { final int p = parent(n); fixAggregates(n); switch (balanceFactor(n)) { case -2: final int right = right(n); if (balanceFactor(right) == 1) { rotateRight(right); } rotateLeft(n); break; case 2: final int left = left(n); if (balanceFactor(left) == -1) { rotateLeft(left); } rotateRight(n); break; case -1: case 0: case 1: break; // ok default: throw new AssertionError(); } n = p; } }
private void release(int node) { left(node, NIL); right(node, NIL); parent(node, NIL); nodeAllocator.release(node); }