Run the rank to zero. When the binary search continues from the root, add the sizes of all the left subtrees that the search will scan, including the left subtree of the found node.
Ie, when the search goes to the left (from the parent to the left child), it does not detect new values less than the found element, so the ranking remains unchanged. When it goes right, the parent plus all the nodes in the left subtree are smaller than the item found, so add one plus the size of the left subtree. When he finds the item he is looking for. all elements in the left subtree of the node containing the element are smaller than it, so add this to the rank.
Putting it all together:
int rank_of(NODE *tree, int val) {
int rank = 0;
while (tree) {
if (val < tree->val)
tree = tree->left;
else if (val > tree->val) {
rank += 1 + size(tree->left);
tree = tree->right;
}
else
return rank + size(tree->left);
}
return NOT_FOUND;
}
Returns rank zero. If you need 1-based, then initialize rankto 1 instead of 0.
source
share