码迷,mamicode.com
首页 > 其他好文 > 详细

数据结构-数据结构的扩展

时间:2018-03-28 20:34:03      阅读:125      评论:0      收藏:0      [点我收藏+]

标签:size   node   附加   个数   end   路径   成员   操作   start   

1 如何做数据扩张

4个步骤:

  1. 选择一种基础数据结构

  2. 确定基础数据结构中要维护的附加信息

  3. 检查基础数据结构上一些操作是否需要维护附加信息

  4. 为附加信息添加一些新的操作

 

2 举例

扩展红黑树(或是其他树),能够在O(lgn)内获取第i小的元素.

为每个节点添加一个size成员变量,表示当前节点所有子节点的个数+1,加1是因为自己还有一个.因此:

 pre->size=pre->left->size+pre->right->size+1; 

 

要想找到第i小的元素

RBNode* RBTree::find(size_t i)
{
  return axu_find(mp_root,i);
}

RBNode* RBTree::aux_find(RBNode* cur,size_t i)
{
  size_t index = cur->left->size+1;//当前节点在书中的序号,秩
  if(index==i)
  {
    return cur;
  }else if(index < i){ //i还有在 cur 的后面
	return aux_find(cur->right,i-r);// i-r 表示,之前已经有r个了,再往后找i-r个就是了
  }else if(index > i){ // i 在 cur 的前面
    return aux_find(cur->left);  // 没有跳过任何元素,因此直接传 i
  }
}

 

相对应的,也可以找到第i大的元素,也就是根节点size-i+1小的元素.

 

确定一个节点在树中的是第几小的.

 

size_t* RBTree::find(RBNode *node)
{
  size_t index = node->left->size+1; // 这只是自己统治下节点的排序.
  RBNode* pre = node;
  while(pre != mp_root)
  {
    //只有自己是一个右节点的时候,才要加上左节点的元素数目,如果不是,就不加.
    if(pre == pre->p->right)
    {
      r=r+pre->p->left->size+1; //自己父节点的右子树个数 + 父节点的1
    }
    pre = pre->p;
    //向上递归,直到p是根节点.
  }
}

 

size的维护

 

插入过程:

  • 添加元素时,所有元素途径的路径上 size+1,添加以后,自己的size=1,O(lgn)

  • 旋转,以左旋为例: 原先父节点pre,旋转以后父节点cur

    新的父节点的size等于原先父节点的size.(因为元素个数没变)

    原先父节点的个数变为 pre->size=pre->left->size+cur->right->size+1

删除过程:

  • 删除操作,遍历路径从根节点到节点replace_node,路径上所有节点size-1

  • 旋转,同插入

数据结构-数据结构的扩展

标签:size   node   附加   个数   end   路径   成员   操作   start   

原文地址:https://www.cnblogs.com/perfy576/p/8665672.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!