I’m trying to implement the OS-Rank() function for my binary tree that I’ve built. OS-Rank tags a node with a count of smaller nodes from the tree, and stores it in node.size. This allows OS-Select to easily select the i’th smallest node in O(nlgn) time.
Here is the pseudo code:
OS-RANK(x)
r = x.left.size + 1
y = x
while y != T.root
if y == y.parent.right
r = r + y.parent.left.size + 1
y = y.parent
return r
Here’s my code:
def osrank(self, root):
r = 0
if self.left != None:
r = self.left.size + 1
else:
r += 1
y = self
while y != root:
if y == y.parent.right:
if y.parent.left != None:
r = r + y.parent.left.size + 1
else:
r += 1
y = y.parent
self.size = r
Not too different, except that I had to handle cases where nodes were null.
However, when I print out my in order traversal after inserting {5,2,7,1,6}, I get this:
L L 1(1) U 2(1) U 5(1) R L 6(3) U 7(3) U U
(L/U/R describes traversals, and the number in brackets is node.size, or the rank).
I think I’m expecting something like this:
L L 1(1) U 2(2) U 5(5) R L 6(1) U 7(2) U U
Any advice?
Embarrassingly, I’ve misunderstood the purpose of OS-Rank(). I thought it set the size value of each node, but it appears that’s actually done on insert. OS-Rank() returns the rank of a node by using that size value.
No more 2am coding, I promise!