OS-SELECT-NONRECURSIVE(T, i) while True r = x.left.size + 1 if i == r return x else if i < r x = x.left else x = x.right i = i - r
17.1-4
如下是OS-KEY-RANK的伪代码,它是自顶向下实现的。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
OS-KEY-RANK(T, k) x = T.root rk = 0 while x != T.nil r = x.left.size + 1 if x.key < k rk = rk + r x = x.right else if x.key == k rk = rk + r return rk else x = x.left // k不在T中,那么有rk个比k小的键。 return rk + 1
OS-INSERT'(T, z) x = T.root y = T.nil while x != T.nil y = x if z.key < x.key x.rank' = x.rank' + 1 x = x.left else x = x.right z.p = y if y == T.nil T.root = z else if z.key < y.key y.left = z else y.right = z z.left = T.nil z.right = T.nil z.color = RED z.rank' = 1 OS-INSERT-FIXUP'(T, z)
OS-DELETE'(T, z) y = z y-original-color = y.color if z.left == T.nil x = z.right RB-TRANSPLANT(T, z, z.right) else if z.right == T.nil x = z.left RB-TRANSPLANT(T, z, z.left) else y = RB-MINIMUM(T, z.right) y-original-color = y.color x = y.right if y != z.right RB-TRANSPLANT(T, y, y.right) y.right = z.right y.right.p = y else x.p = y RB-TRANSPLANT(T, z, y) y.left = z.left y.rank' = z.rank' y.left.p = y y.color = z.color w = x while w != T.root if w == w.p.left w.p.rank' = w.p.rank' - 1 w = w.p if y-original-color == BLACK OS-DELETE-FIXUP'(T, x)
OS-LEFT-ROTATE'(T, x) y = x.right x.right = y.left if y.left != T.nill y.left.p = x y.p = x.p if x.p == T.nil T.root = y else if x == x.p.left x.p.left = y else x.p.right = y y.left = x x.p = y y.rank' = y.rank' + x.rank'
OS-RIGHT-ROTATE'(T, y) x = y.left y.left = x.right if x.right != T.nil x.right.p = y x.p = y.p if y.p == T.nil T.root = x else if y == y.p.left y.p.left = x else y.p.right = x x.right = y y.p = x y.rank' = y.rank' - x.rank'
CAL-INVERSION'(A, n) let T be a new red-black tree that support size attribute. inversion = 0 for i = 1 to n Let p be a new node p.key = A[i] p.left = T.nil P.right = T.nil OS-INSERT(T, p) inversion = inversion + (i - OS-RANK(T, p))
// 计算树中有多少个键小于k OS-LT-OR-LE-COUNT(T, k, op) x = T.root count = 0 while x != T.nil r = x.left.size + 1 if (op == LT and x.key < k) or (op == LE and x.key <= k) count = count + r x = x.right else x = x.left return count
CAL-PAIRS-INTERSECT(C, n) let T be a new red-black tree that support size attribute. for i = 1 to n if C[i].left > C[i].right exchange C[i].left with C[i].right sort C by C[i].left nondecreasingly pairs-cnt = 0 for i = 1 to n t = OS-LT-OR-LE-COUNT(T, C[i].right, LT) - OS-LT-OR-LE-COUNT(T, C[i].right, LE) pairs = pairs + t Let p be a new node p.key = C[i].right p.left = T.nil P.right = T.nil OS-INSERT(T, p) return pairs