按序号索引二叉树

  理论上,一个平衡的二叉树,可以在 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
};

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值