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

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

 //int A[],L,R,k;for i = L to RA[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。

利用伸展树提高区间操作的性能相关推荐

  1. Splay伸展树入门(单点操作,区间维护)附例题模板

    Pps:终于学会了伸展树的区间操作,做一个完整的总结,总结一下自己的伸展树的单点操作和区间维护,顺便给未来的自己总结复习用. splay是一种平衡树,[平均]操作复杂度O(nlogn).首先平衡树先是 ...

  2. BZOJ-4811: [Ynoi2017]由乃的OJ (树链剖分 线段树维护区间操作值 好题)

    4811: [Ynoi2017]由乃的OJ Time Limit: 6 Sec  Memory Limit: 256 MB Submit: 366  Solved: 118 [Submit][Stat ...

  3. poj3580 伸展树(区间翻转 区间搬移 删除结点 加入结点 成段更新)

    好题.我做了很久,学了大牛们的区间搬移.主要的代码都有注释. #include<cstdio> #include<cstring> #include<iostream&g ...

  4. Tree | 伸展树

    本文目录 一.伸展树的基本概念 二.Splay -- 伸展操作的原理 1.P 是根节点 2.P 不是根节点 Z字型旋转(Zig-zag) 一字型旋转(Zig-zig)-- 左 一字型旋转(Zig-zi ...

  5. 伸展树(Splay tree)浅谈

    树看的越来越多,越来越神奇. 看伸展树这种神级数据结构之前,建议大家首先彻底明白二叉搜索树,这是万树的基础. 然后可以去看下treap,最好再去看下红黑树.如果有线段树的基础那更好了,我们会发现线段树 ...

  6. 伸展树的基本操作与应用 IOI2004 国家集训队论文 杨思雨

    伸展树的基本操作与应用 安徽省芜湖一中 杨思雨 [关键字] 伸展树 基本操作 应用 [摘要] 本文主要介绍了伸展树的基本操作以及其在解题中的应用.全文可以分为以下四个部分. 第一部分引言,主要说明了二 ...

  7. Splay Tree伸展树

    伸展树基本概念 伸展树的基本思想. 伸展树完全是基于局部性原理(locality)的. 局部性原理是计算机科学中非常重要的原理,很多设计,比如说多级存储器,缓存,都是基于局部性原理.简单说来就是< ...

  8. 数据结构--伸展树(伸展树构建二叉搜索树)-学习笔记

    2019/7/16更新:封装SplayTree进入class:例题:http://poj.org/problem?id=3622 一个伸展树的板子: #include<stdio.h> # ...

  9. 高级数据结构实现——自顶向下伸展树

    [0]README 1) 本文部分内容转自 数据结构与算法分析,旨在理解 高级数据结构实现--自顶向下伸展树 的基础知识: 2) 源代码部分思想借鉴了数据结构与算法分析,有一点干货原创代码,for o ...

最新文章

  1. tomcat + memcached session manager共享session
  2. 在iOS 中使用sleep方法 让程序暂停几秒钟
  3. 分布式系统理论基础 - 一致性、2PC和3PC
  4. arcgis api for js入门开发系列十八风向流动图
  5. centos打显卡驱动命令_Centos7更新内核后安装N卡驱动一键配置脚本
  6. 5.七个重点网络协议
  7. jxl java mer_导出报表出错,有没有大神懂得
  8. kali-扫描主机-Nmap
  9. mysql创建视图步骤_MySQL创建视图的详细步骤
  10. 在window系统上对web项目进行safair兼容测试
  11. 讲讲多拨的额外骚操作(多拨附加教程)
  12. 揭秘京东区块链开源项目——JD Chain
  13. Java基础之入门(一)
  14. 你究竟有多了解开源?InfoQ《中国开源发展研究分析 2022 》发布
  15. 数据分析进阶 - 使用Pyecharts搭建数据看板
  16. 数据结构通过链表实现班级同学通讯录
  17. 小米盒子 android 动画特效,小米盒子3安装这些软件 丰富娱乐功能
  18. linux 解压tgz文件
  19. php get your hands dirty,BBC地道英语:To Get your Hands Dirty 亲自动手
  20. cz73 读取速度慢_U盘读写速度变慢的原因详解

热门文章

  1. Oracle修改字段的顺序
  2. Android ViewPager指示器
  3. android 动态设置View的高度和宽度,ViewTreeObserver使用
  4. Win7下IIS7 ASP出现HTTP 500错误的解决办法
  5. c语言插件实现原理,C语言实现插件机制
  6. bem什么意思_BEM命名法
  7. 【C语言进阶深度学习记录】九 C语言中const的详细分析
  8. 【C语言进阶深度学习记录】八 C语言中void的分析
  9. 【常见笔试面试算法题12续集三】动态规划算法案例分析3 LIS练习题(最长上升子序列)
  10. Flag counter被博客园禁了的解决方法