利用伸展树提高区间操作的性能

伸展树是一种优化查找和插入性能的数据结构,通过每次操作将节点旋转到树根来确保高频节点靠近根部。在区间操作中,伸展树能够通过分离和合并区间实现高效操作,例如对序列的[L,R]区间执行加法操作,其性能优于普通数组和某些平衡树。" 83274695,7422849,Logistic Regression在评分卡模型的应用详解,"['机器学习', '统计模型', '风险管理', '信用评估', '数据挖掘']
摘要由CSDN通过智能技术生成

一、首先,什么是区间操作?以及各种数据结构性能对比

区间操作就是对一个序列的某个区间的所有元素进行的操作。比如,对区间所有元素增加一个值,翻转区间元素等。
对区间操作,最普通的方法就是数组。比如:对一个长为N 的序列的 [L,R]区间执行每个元素加上k 的操作,可以使用数组来保存序列,然后使用循环对[L,R]区间每个元素加k
代码是这样的:

 //int A[],L,R,k;
 for i = L to R
    A[i] += k;   

这样做的效率是 O(N),对于一个排序来说这是很好的性能,但对于一个操作来说,这并不是理想,很多二叉树的操作都能达到O( log N) 级别。
对于最典型的查找操作,普通二叉树的操作能达到O( log N) ,但是树在最坏情况下性能会退化到O(N)(比如順边的情况下) 。
平衡树能对树高度进行控制,最坏性能控制在O(log N),但是,平衡树只是控制了树的高度,而不能保证访问频率高的节点离跟越近,因此,平衡树的访问效率与节点的分布有关,如果访问频率高的节点离根很远,那么平衡树的性能就会有所降低。
因此,便有了伸展树。伸展树的特点就是:每次查找或插入节点,都会把该节点旋转到树根位置,随着操作次数增加,高频节点就会聚集在根周围,从而达到较好的性能。

二、伸展树介绍

伸展树的特点就是:每次查找或插入节点,都会把该节点旋转到树根位置,随着操作次数增加,高频节点就会聚集在根周围,从而达到较好的性能。

伸展树首先是一棵树,可以定义如下:

typedef struct Node
{
    int key;    
    struct Node *lch,*rch,*parent;
}* Node ,* Tree;

伸展树的高层操作有:

高层操作实现
insert( t , x )将x插入t中。找到x在t中的位置,插入x,然后再将x旋转到树根
delete( t ,x )删除x。找到x,将x调到根部,将x的左子树和右子树删除后合并。
spilt( t , x)以x为界分离t。找到x,将x旋转到树根,然后将x的左子树和剩余部分分离
find( t , x )找到x。找到x,然后将x旋转到树根。
join( t1 , t2 )合并子树 t1和t2,要求t1所有元素小于t2的任一元素。找到t1的最大元素,并调整到根部,将t2作为根的右子树插入

可见,树的高层操作都依赖与旋转等基本操作:

基本操作实现
splay( t ,x )将x调至根部。循环调用zig_zag_manager( t , x) 方法,直到x == t
zig_zag_manager( t , x)旋转管理者。 找到x,分析x与父亲节点,父亲节点与祖父节点的关系,选择恰当的旋转方式。
下面几个函数中,设x 的父节点为 p, p的父节点为g 。
zig( t , x )右旋。当p是根节点,x是p的左孩子,将x右旋
zag( t , x )左旋。当p是根节点,x是p的右孩子,将x左旋
zig_zig( t , x )右双旋。x是p的左节点,当p是g的左节点,先将p右旋,再将x右旋
zag_zag( t , x )左双旋。x是p的右节点,当p是g的右节点,先将p左旋,再将x左旋
zig_zag( t , x )右旋再左旋。x是p的左节点,当p是g的右节点,先将x右旋,再将x左旋
zag_zig( t , x )左旋再右旋。x是p的右节点,当p是g的左节点,先将x左旋,再将x右旋

其实上述左旋和右旋很有规律,当一个节点是左节点时,应当右旋,当一个节点是右节点时,应当左旋。

伸展树的区间操作

伸展树操作区间的思路是:

第一步,分离区间。分离长度为N的序列里的区间 [L ,R ],首先找到第L大的元素,然后以其为界进行分离操作,得到t1 = [0,L-1] 和 temp = [L ,N]。
然后,再找到 temp 中第 R-L+1 大元素,并以该元素为界进行分离操作, 得到 t2 = [L ,R] 和 t3 = [R+1, N]。这样,就成功分离出了目标区间t2 。

第二步,对目标区间进行操作。

第三步,合并区间。合并t1,t2,t3。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值