利用红黑树可以早lg(n)内查找任意个顺序统计量,这比前面讲到的在O(n)内查找效率要高,但是实现起来比较麻烦。在前面红黑树的基础上实现就比较简单,在树的节点域上加上size整型变量,用来标记以该节点为根的树中有多少节点。特别的叶子节点的size为1.在红黑树中需要修改的是在插入和删除节点时记得要重新调整size的数值,本代码中利用中序遍历的方法对size重新调整:代码如下:
void SizeAdjust(BRTreeNode*node)
{
if(node!=nil)
{
SizeAdjust(node->left);
SizeAdjust(node->right);
node->size=node->left->size+node->right->size+1;
}
}
如果想查找树中第i小的顺序统计量只需找到根节点左边的size为i-1的节点,或根节点右边的size为i-1-size(root)的节点,该节点的父节点即为i小顺序统计量。文字表述可能不清楚,代码如下:
BRTreeNode*GetIthnode(BRTreeNode*node,int num)
{
int r=node->left->size+1;
if(r==num)
{
return node;
}
else if(r>num)
{
return GetIthnode(node->left,num);
}
else
{
return GetIthnode(node->right,num-r);
}
}
该代码在红黑树的博客算法导论第十三章--红黑树C++代码实现中可以直接运行,只是红黑树要稍作修改。