splay树

splay树(伸展树):

概述:二叉查找树的一种改进数据结构,为了使整个查找时间更小,被查频率高的那些节点应当经常处于靠近树根的位置;因此,每次查找节点之后对树进行重构,把被查找的节点搬移到树根,这种自调整形式的二叉查找树就是伸展树。

平摊时间复杂度:O(logn)

基本操作:通过旋转的方法把被访问节点旋转到树根的位置,同时不打乱数列中数据大小关系(指中序遍历结果是全序的),伸展树主要有三种旋转操作:单旋转,一字形旋转和之字形旋转。

代码:(旋转操作)

void rotate(long x,int kind)  
//kind=0表示左旋,kind=1表示右旋 ch[X][0..1]表示X的左儿子和右儿子  
{  
     long y=father[x];  long z=father[y];  
     ch[y][!kind]=ch[x][kind];
	 if(!ch[x][kind])
	    father[ch[x][kind]]=y;  
     father[x]=z;
	 if(z!=-1)
	    ch[z][ch[z][1]==y]=x;  
     father[y]=x;  ch[x][kind]=y;  
}   
代码:(Splay操作)

void splay(long x)  
{  
    while(father[x]!=-1)  
    {  
        long y=father[x];  long z=father[y];  
        if(z==-1)//单旋转 
		    rotate(x,ch[y][0]==x);  
        else  
        {  
            if(ch[z][0]==y)//一字形旋转  
            {  
                if(ch[y][0]==x)
				    rotate(y,1),rotate(x,1);  
                else           
				    rotate(x,0),rotate(x,1);  
            }  
            else//之字形旋转  
            {  
                if(ch[y][1]==x)
				    rotate(y,0),rotate(x,0);  
                else           
				    rotate(x,1),rotate(x,0);  
            }  
        }  
    }  
    root=x;  
}  

应用:

1. 插入:在当前数列第posi 个数字后面插入tot 个数字;若在数列首位插入,则posi 为0。

2. 删除:从当前数列第posi 个数字开始连续删除tot 个数字。

3. 修改:从当前数列第posi 个数字开始连续tot 个数字统一修改为c 。

4. 翻转:取出从当前数列第posi 个数字开始的tot 个数字,翻转后放入原来的位置。

5. 求和:计算从当前数列第posi 个数字开始连续tot 个数字的和并输出。

6. 求和最大子序列:求出当前数列中和最大的一段子序列,并输出最大和。


未完待续...
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值