按序号索引二叉树
理论上,一个平衡的二叉树,可以在 O(logn)时间内,按中序遍历的顺序号(或者说下标)完成对结点的搜索。不过,这需要在每个结点上存储以该结点为根的子树的大小,通过增加存储的途径,来改善性能。
如果这是一棵排序树,那么这个序号就是按大小排列的顺序号。
但是如果这颗树在程序运行过程中有对结点的动态插入和删除(插入和删除时,以及调整平衡性时,都需要调整插入/删除结点路径上的Node.count,时间复杂度为O(logn)),那么每个结点的序号就是变化的。
因此,不能把序号存储在某个地方,然后又企图根据这一序号,重新找到该序号先前对应的那个结点。可能时因为这个原因,在很多时候,没有对这种计算的需求。我目前还没有在什么地方看到过这方面的文章。自己苦思冥想,竟也完成了。
class Node
{
public:
Node* getByIndex(int index)
{
Node* p = this;
while (p)
{
Node* q = p->left;
while (q && q->count > index)
{
p = q;
q = q->left;
}
if (0 == q || q->count == index) return p;
p = p->right;
index–;
if (q) index -= q->count;
}
return 0;
}
private:
Node *left, *right;
int count; // node count of ‘this’ and its subtree
};