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

学习笔记:Splay

时间:2018-04-01 13:17:06      阅读:121      评论:0      收藏:0      [点我收藏+]

标签:简单   步骤   操作   网上   改变   body   设定   log   play   

好像是一种非常重要的数据结构……?

哦Splay本质其实是颗二叉查找树。

什么是二叉查找树?

定义……记住就好了。就是一棵树(空树也是二叉查找树……)

对于一棵树的任意结点

若左子树不为空,则左子树的值都小于该节点的值

若右子树不为空,则右子树的值都大于该节点的值

树中没有权值相同的节点(因为相同的权值都被合并在一个节点上了,不过讲道理也可以等于,记得做过一个题,只不过可能处理起来比较麻烦)。

SplayNB在哪里?

普通的二叉查找树很容易被卡……比如输入数据递增/递减,那么就被卡成树高为n了emm

而Splay可以让树不断旋转,以维持这棵树不过高

普通二叉查找树的操作=w=

懒得写了……普通二叉查找树的操作非常好懂网上就有

Splay的旋转操作

对于节点x,我们改变其祖父和父亲的值。

1、如果三点一线先转父亲,否则就先转x。 2、转x

重复上面的步骤,改变他们的父子关系。这样一直把x做到根。

很容易发现这棵树的中序遍历是不会改变的(这非常重要)

那么二叉查找树的性质仍然满足,只不过树高被调整了。

Splay的二叉查找树操作

这个很简单,和普通二叉查找树一样,只不过对一个点x操作过后,将其splay到根以保证树高不过高就好了。

Splay的区间操作

这里一开始并不是很理解,但只要知道一棵树旋转操作是不会改变其中序遍历的。

那么我们用中序遍历保存原序列,然后就可以和线段树一样打标记pushdown还有pushup维护区间信息了。

假设想操作区间[l,r],我们就将l-1,r+1的点分别转到根/根的右儿子

那么r+1有且仅有一个儿子,为左儿子。左儿子的子树就是我们要找的区间,然后就可以在上面打标记操作了。

为了防止越界,设定1和n+2节点为哨兵节点。那么若要将l-1,r+1的点分别转到根/根的右儿子,则变成了操作树上的l节点和r+2节点转上去

学习笔记:Splay

标签:简单   步骤   操作   网上   改变   body   设定   log   play   

原文地址:https://www.cnblogs.com/refun/p/8686092.html

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