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

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

区间操作就是对一个序列的某个区间的所有元素进行的操作。比如,对区间所有元素增加一个值,翻转区间元素等。
对区间操作,最普通的方法就是数组。比如:对一个长为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。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/430230.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

python书写风格_以下两种风格 Python 写法,请问大家倾向哪种:)

看到不同的同事代码,表达同一个意思,主要 if 部分以下哪种写法比较好些:) 第一种写法 def xxxx(ph, sin_id): """ """ with OracleConnect(xxxx) as db_oracle: sql u"xxxxx" has_data,…

中科大开源镜像使用帮助列表

https://lug.ustc.edu.cn/wiki/mirrors/help转载于:https://www.cnblogs.com/hikecn/p/5797959.html

伸展树的代码实现

一、伸展树的数据结构 typedef struct Node {int key; struct Node *lch,*rch,*parent; }* Node ,* Tree; 二、伸展树的基础操作 下面几个函数中,设x 的父节点为 p, p的父节点为g 。 zig( t , x ) 右旋。当p是根节点,x是p的左孩子,将…

枚举命名规范_UE4 C++基础教程 - 编码规范

为什么要学习编码规范?良好的编码规范不仅利于项目维护,也增加了代码辨识度。使我们在阅读代码时能够更加清晰的理解代码意图。维护编码规范不是一件机械化的工作,它更像是一门艺术,让我们在有限的规范内发挥自己的创造力。除此之…

Cocos2d-x之Log输出机制

| 版权声明:本文为博主原创文章,未经博主允许不得转载。 在cocos2d-x中,我们使用log这个函数进行输出,log可以输出很多参数,它的使用方式就和使用c语言中的printf的使用方式差不多。log其实是一个跨平台的日志输出的…

最佳单例模式

initialization on demand holder 模式分析 单例模式要求在应用运行的过程中,只有一个类的实例存在。因此,要确保创建过程是线程安全的,同时要兼顾性能。目前了解到做得比较好的,就是这种initialization on demand holder模式&am…

python接口测试jason_Python 接口测试之Json数据文件操作

引言 前面说过接口测试就是数据的测试,在测试之前,需要准备好测试数据,而测试数据可以用数据库、excel、txt和csv方式,当然还有一种方式,那就是使用json文件来储存测试数据。常用的方式就是这些。 设计思路 python读取…

城市轮廓线求解

问题描述 每一个建筑物用一个三元组表示(L, H, R), 表示左边界, 高度和右边界,轮廓线用X,Y,X,Y…这样的交替式表示,给N个建筑,求轮廓线。 总体思路 首先,要将建筑物离散成点或线,方便运算。将建筑物表示成(L,H),(R,…

wpf的listbox循环数据滚动_滚动版 CentOS Stream 和 Fedora 的关系

如果 CentOS 现在位于 RHEL 的上游,那么 Fedora 会发生什么?那不是 Fedora 在 Red Hat 生态系统中的角色吗?-- Matthew Miller(作者)一封来自 Fedora 项目负责人办公室的信件:(LCTT 译注&#x…

位运算的妙用

位运算所有语言里面都有位运算&#xff0c;&&#xff0c;|,^,~,<<,>>,>>>&#xff0c;但是其他语言不清楚&#xff0c;前端估计许多人直接一扫而过&#xff0c;甚至把这玩意和逻辑或与混淆&#xff0c;甚至有的不认识<<,>>>,问这什么意…

AJAX中的跨域问题:什么是跨域?如何解决跨域问题?

域不一样的&#xff0c;即为跨域&#xff0c;包括&#xff08;协议&#xff0c;域名&#xff0c;端口号&#xff09; 1. 指定允许其他域名访问 header(Access-Control-Allow-Origin:*); 2.使用jsonp转载于:https://www.cnblogs.com/luckyXcc/p/5805909.html

求无序序列每个元素最接近的值

1、问题描述 给一个n个元素的线性表A&#xff0c;对于每个数Ai&#xff0c;找到它之前的数中&#xff0c;和它最接近的数。 即对于每个i&#xff0c;求 Ci min{ |Ai -Aj | | 1< j < i} 1.2算法分析 有两种思路可以解决上诉问题&#xff1a; &#xff08;1&#xff0…

python把list转成字典_python中将list转为dict

最近在项目中经常遇到将list转为dict形式&#xff0c;之前都只会用for循环&#xff0c;取出list中的每个值&#xff0c;update到dict中。 示例1 scrabble_scores [(1, "E A O I N R T L S U"), (2, "D G"), (3, "B C M P"), (4, "F H V W …

maven引入springframework的猫腻

看官网的quickstart&#xff0c;以为maven只要将quickstart里的配置复制到项目里就好了&#xff0c;但是在项目中使用jdbc和事物时&#xff0c;都提示找不到相关的类&#xff0c;才知道原来官网文档还有猫腻。 maven引入spring框架 project下框架有点多&#xff0c;点spring …

BAT批量处理 命令

第一章 批处理基础第一节 常用批处理内部命令简介批处理定义&#xff1a;顾名思义&#xff0c;批处理文件是将一系列命令按一定的顺序集合为一个可执行的文本文件&#xff0c;其扩展名为BAT或者CMD。这些命令统称批处理命令。小知识&#xff1a;可以在键盘上按下CtrlC组合键来强…

bigdecimal 小于等于0_半场0-0比分的比赛,你需要注意这些

大家好&#xff0c;我是师弟&#xff0c;今天给大家带来有关于半场0-0比赛的分析。前段时间有朋友向我吐槽道&#xff1a;“最近买半场0-0的比赛输惨了”&#xff0c;经过询问了解到他是专挑半场0-0的比赛在中场的时候买入大1.5&#xff0c;没想到输多赢少。而他的想法可能也代…

Spring JdbcTemplate实例

简介 Spring JdbcTemplate类是Spring提供的简化数据库操作的一个类&#xff0c;这个类使用了模板方法模式&#xff0c;可以减少一些重复代码。这里主要演示一下 JdbcTemplate 的使用。 完整的代码看这里&#xff1a;spring_jdbc_01 创建数据库 第一步是创建数据库。下面的S…

JS-为金额添加千分位逗号分割符

前言&#xff1a;这个功能在前端页面中使用的还是比较多的&#xff0c;正好我们的项目中也有使用此功能&#xff0c;不过YY同学写的代码不像个方法的样子&#xff0c;一个入口中间又插了几道子&#xff0c;所 以&#xff0c;我写了下面这个方法&#xff0c;经过测试…

将chart放入panel中出现滚动条_聊天场景在web前端开发中的体验与优化

在日常工作中&#xff0c;如下图的聊天场景是不是很熟悉&#xff0c;没错就是我们再熟悉不过的 QQ 和微信&#xff0c;一个正常的聊天界面大致上是长这个样子的&#xff1a;这种聊天窗口的消息流有两个明显的特点&#xff1a;最新的消息和滚动条初始位置需要在列表的最底部下拉…

一个(伪)MaterialDesign风格的博客园皮肤

皮肤长什么样&#xff0c;不用我说&#xff0c;相信各位点进来的看官都能看得一清二楚。 有关其他细节呢&#xff0c;也欢迎各位在我博客里逛逛&#xff0c;帮忙挑挑刺&#xff0c;提提建议。 由于水平有限&#xff0c;暂没能用CSS处理博客园的代码高亮字体&#xff0c;实在是有…