算法合集之《左偏树的特点及其应用》-讲义
- 格式:ppt
- 大小:317.50 KB
- 文档页数:4
左偏树的特点及其应用广东省中山市第一中学黄源河【摘要】本文较详细地介绍了左偏树的特点以及它的各种操作。
第一部分提出可并堆的概念,指出二叉堆的不足,并引出左偏树。
第二部分主要介绍了左偏树的定义和性质。
第三部分详细地介绍了左偏树的各种操作,并给出时间复杂度分析。
第四部分通过一道例题,说明左偏树在当今信息学竞赛中的应用。
第五部分对各种可并堆作了一番比较。
最后总结出左偏树的特点以及应用前景。
【关键字】左偏树可并堆优先队列【目录】一、引言 (2)二、左偏树的定义和性质 (2)2.1 优先队列,可并堆 (2)2.1.1 优先队列的定义 (2)2.1.2 可并堆的定义 (2)2.2 左偏树的定义 (3)2.3 左偏树的性质 (4)三、左偏树的操作 (6)3.1 左偏树的合并 (6)3.2 插入新节点 (8)3.3 删除最小节点 (9)3.4 左偏树的构建 (9)3.5 删除任意已知节点 (10)3.6 小结 (13)四、左偏树的应用 (15)4.1 例——数字序列(Baltic 2004) (15)五、左偏树与各种可并堆的比较 (18)5.1 左偏树的变种——斜堆 (18)5.2 左偏树与二叉堆的比较 (19)5.3 左偏树与其他可并堆的比较 (19)六、总结 (22)在线代理|网页代理|代理网页|【正文】一、引言优先队列在信息学竞赛中十分常见,在统计问题、最值问题、模拟问题和贪心问题等等类型的题目中,优先队列都有着广泛的应用。
二叉堆是一种常用的优先队列,它编程简单,效率高,但如果问题需要对两个优先队列进行合并,二叉堆的效率就无法令人满意了。
本文介绍的左偏树,可以很好地解决这类问题。
二、左偏树的定义和性质在介绍左偏树之前,我们先来明确一下优先队列和可并堆的概念。
2.1优先队列,可并堆2.1.1优先队列的定义优先队列(Priority Queue)是一种抽象数据类型(ADT),它是一种容器,里面有一些元素,这些元素也称为队列中的节点(node)。
树结构知识点总结一、树结构的基本概念1.1 树的定义与特点树是一种递归的数据结构,它由结点和边组成,具有以下特点:(1)每个结点都有一个父结点,除了根结点;(2)每个结点可能有零个或多个子结点;(3)从根结点到任意结点之间有且仅有一条路径。
1.2 结点、父结点、子结点、根结点、叶子结点在树结构中,结点是树的基本单位,可以包含数据和指向其他结点的指针。
树结构中有一些特殊的结点概念:(1)父结点:一个结点的直接上级结点称为它的父结点;(2)子结点:一个结点的直接下级结点称为它的子结点;(3)根结点:树的顶层结点称为根结点;(4)叶子结点:没有子结点的结点称为叶子结点。
1.3 深度和高度在树结构中,深度是指从根结点到某个结点的唯一路径的长度。
而高度是指树中结点的最大深度。
1.4 子树在树结构中,一个结点以及它的子结点以及它的子结点的子结点构成的树称为子树。
1.5 有序树和无序树树结构分为有序树和无序树。
有序树中子结点的相对位置是重要的,而在无序树中子结点之间的相对位置不重要。
1.6 二叉树二叉树是一种特殊的树结构,每个结点最多有两个子结点,分别称为左子结点和右子结点。
二叉树是计算机科学中最基本的树结构之一。
1.7 二叉树的特殊类型二叉树有很多特殊类型,如满二叉树、完全二叉树、平衡二叉树、二叉搜索树等,它们在不同的场景中有着不同的应用。
1.8 树结构的表示树结构可以用不同的方式来表示,如数组表示、链表表示、层次遍历表示等。
每种表示方式都有其特点和适用场景。
二、树结构的常见应用2.1 文件系统在计算机中,文件系统通常是以树结构来表示的,每个文件夹是一个结点,而文件夹中的文件是它的子结点。
2.2 组织结构组织结构也可以用树结构来表示,每个员工是一个结点,而领导和下属的关系就是结点之间的父子关系。
2.3 数据库索引在数据库中,经常需要对数据进行索引,以提高查询的效率。
索引通常是以树结构的方式来表示的。
2.4 XML文档XML文档是一种非常常见的数据格式,它本质上就是一棵树。
十三、左偏树(Leftist Tree)树这个数据结构内容真的很多,上一节所讲的二叉堆,其实就是一颗二叉树,这次讲的左偏树(又叫“左翼堆”),也是树。
二叉堆是个很不错的数据结构,因为它非常便于理解,而且仅仅用了一个数组,不会造成额外空间的浪费,但它有个缺点,那就是很难合并两个二叉堆,对于“合并”,“拆分”这种操作,我觉得最方面的还是依靠指针,改变一下指针的值就可以实现,要是涉及到元素的移动,那就复杂一些了。
左偏树跟二叉堆比起来,就是一棵真正意义上的树了,具有左右指针,所以空间开销上稍微大一点,但却带来了便于合并的便利。
BTW:写了很多很多的程序之后,我发觉“空间换时间”始终是个应该考虑的编程方法。
:)左偏左偏,给人感觉就是左子树的比重比较大了,事实上也差不多,可以这么理解:左边分量重,那一直往右,就一定能最快地找到可以插入元素的节点了。
所以可以这样下个定义:左偏树就是对其任意子树而言,往右到插入点的距离(下面简称为“距离”)始终小于等于往左到插入点的距离,当然了,和二叉堆一样,父节点的值要小于左右子节点的值。
如果节点本身不满,可插入,那距离就为0,再把空节点的距离记为-1,这样我们就得出:父节点的距离= 右子节点距离+ 1,因为右子节点的距离始终是小于等于左子节点距离的。
我把距离的值用蓝色字体标在上图中了。
左偏树并一定平衡,甚至它可以很不平衡,因为它其实也不需要平衡,它只需要像二叉堆那样的功能,再加上合并方便,现在来看左偏树的合并算法,如图:这种算法其实很适合用递归来做,但我还是用了一个循环,其实也差不多。
对于左偏树来说,这个合并操作是最重要最基本的了。
为什么?你看哦:Enqueue,我能不能看作是这个左偏树的root和一个单节点树的合并?而Dequeue,我能不能看作是把root节点取出来,然后合并root的左右子树?事实上就是这样的,我提供的代码就是这样干的。
Conclusion:左偏树比同二叉堆的优点就是方便合并,缺点是编程复杂度略高(也高不去哪),占用空间稍大(其实也大不去哪)。
树形结构左右值存储,移动节点详解最近做⼀个程序,⽤到树形结构,并且要存储到数据库中。
于是研究了⼀下树形结构的左右值存储。
左右值虽然取⽗祖节点和⼦孙节点,查找节点路径⾮常⽅便,但要找某节点的⽗节点,⼦节点和兄弟节点就⽐较困难,所以还要需要⼀个层级维度⽅便确定⽗⼦和兄弟节点,也就是树形结构中所说的树的深度。
下⾯列举⼀些普通的左右值算法,⽹上有⼤量的资料,就不细说了。
以下资料来⾃⽹上,错误的地⽅我已纠正⼀、计算某节点的⼦孙节点数。
⼦孙节点数量 = (节点右值-节点左值-1)/2⼆、查找某节点的所有⼦孙节点。
select * from tree where L > 节点左值 and R < 节点右值 order by L asc;三、查找某节点的所有⽗祖节点。
select * from tree where L < 节点左值 and R > 节点右值 order by L desc;四、某节点所处层级。
select count(*) from tree where L <= 节点左值 and R >= 节点右值五、增加节点。
需要为要增加的节点腾出左右值的空间。
然后将新节点插⼊数据库。
在哪⾥增加?这就需要参照物,有下⾯四种情况。
1.在A节点下增加⼦节点B,B作为第⼀个⼦节点。
#更新受影响节点update tree set L = L + 2 where L > A节点左值;update tree set R = R + 2 where R > A节点左值;#插⼊新增的节点insert into tree (name, L, R) values('B', A节点左值+1, A节点左值+2);2.在A节点下增加⼦节点B,B作为最后⼀个⼦节点。
#更新受影响节点update tree set L = L + 2 where L >= A节点右值;update tree set R = R + 2 where R >= A节点右值;#插⼊新增的节点insert into tree (name, L, R) values('B', A节点右值, A节点右值+1);3.在A节点后⾯增加节点B, B作为A的兄弟节点。