结构之美——优先队列基本结构(四)——二叉堆、d堆、左式堆、斜堆
实现优先队列结构主要是通过堆完成,主要有:二叉堆、d堆、左式堆、斜堆、二项堆、斐波那契堆、pairing 堆等。
1. 二叉堆
1.1. 定义
完全二叉树,根最小。
存储时使用层序。
1.2. 操作
(1). insert(上滤)
插入末尾 26,不断向上比较,大于26则交换位置,小于则停止。
(2). deleteMin(下滤)
提取末尾元素,放在堆顶,不断下滤:
(3). 其他操作:
都是基于insert(上滤)与deleteMin(下滤)的操作。
减小元素:减小节点的值,上滤调整堆。
增大元素:增加节点的值,下滤调整堆。
删除非顶点节点:直接删除会出问题。方法:减小元素的值到无穷小,上滤后删除。
Merge:insert one by one
2. d叉堆
2.1. 定义
完全d叉树,根最小。
存储时使用层序。
2.2. 操作:
操作跟二叉堆基本一致:insert,deleteMin,增大元素,减小元素,删除非顶元素,merge。
2.3 二叉堆与d叉堆的对比:
3. 左式堆
3.1. 定义

3.2. 操作:
(1) merge :


(1.3).H1根有右孩子
1.初始状态,H1的根6,H2的根为8,将H2合并到H1。
2.将H1构造成根无右孩子的形式:
3.将元素10, merge到H2,要首先将H2构造成根无右孩子的形式,递归,merge,若出现不满足:零路径长:左儿子≧右儿子,交换左右孩子……
——》
——》
——》
4.
5.
3.3. 性质分析:
4. 斜堆
4.1. 定义

4.2性能比较:
定義
- 僅有一個節點的樹為斜堆;
- 兩個斜堆合併的結果仍為斜堆。
合併操作
斜堆合併操作的遞歸合併過程和左偏樹完全一樣。假設我們要合併 A 和 B兩個斜堆,且 A 的根節點比 B 的根節點小,我們只需要把 A 的根節點作為合併後新斜堆的根節點,並將 A 的右子樹與 B 合併。由於合併都是沿著最右路徑進行的,經過合併之後,新斜堆的最右路徑長度必然增加,這會影響下一次合併的效率。所以合併後,通過交換左右子樹,使整棵樹的最右路徑長度非常小(這是啟發規則)。然而斜堆不記錄節點的距離,在操作時,從下往上,沿著合併的路徑,在每個節點處都交換左右子樹。通過不斷交換左右子樹,斜堆把最右路徑甩向左邊了。
遞歸實現合併
- 比較兩個堆; 設p是具有更小的root的鍵值的堆,q是另一個堆,r是合併後的結果堆。
- 令r的root是p(具有最小root鍵值),r的右子樹為p的左子樹。
- 令r的左子樹為p的右子樹與q合併的結果。
舉例。合併前:
合併後
非遞歸合併實現
- 把每個堆的每棵(遞歸意義下)最右子樹切下來。這使得得到的每棵樹的右子樹均為空。
- 按root的鍵值的升序排列這些樹。
- 迭代合併具有最大root鍵值的兩棵樹:
- 具有次大root鍵值的樹的右子樹必定為空。把其左子樹與右子樹交換。現在該樹的左子樹為空。
- 具有最大root鍵值的樹作為具有次大root鍵值樹的左子樹。
舉例:
5. 总结
如果是不支持所谓的合并操作union的话,普通的堆数据结构就是一种很理想的数据结构(堆排序)。 但是如果想要支持集合上的合并操作的话,最好是使用二项堆或者是斐波那契堆,普通的堆在union操作上最差的情况是O(n),但是二项堆和斐波那契堆是O(lgn)。
结构之美——优先队列基本结构(四)——二叉堆、d堆、左式堆、斜堆的更多相关文章
- 数据结构与算法——优先队列类的C++实现(二叉堆)
优先队列简单介绍: 操作系统表明上看着是支持多个应用程序同一时候执行.其实是每一个时刻仅仅能有一个进程执行,操作系统会调度不同的进程去执行. 每一个进程都仅仅能执行一个固定的时间,当超过了该时间.操作 ...
- 树(二叉树 & 二叉搜索树 & 哈夫曼树 & 字典树)
树:n(n>=0)个节点的有限集.有且只有一个root,子树的个数没有限制但互不相交.结点拥有的子树个数就是该结点的度(Degree).度为0的是叶结点,除根结点和叶结点,其他的是内部结点.结点 ...
- 自己动手实现java数据结构(六)二叉搜索树
1.二叉搜索树介绍 前面我们已经介绍过了向量和链表.有序向量可以以二分查找的方式高效的查找特定元素,而缺点是插入删除的效率较低(需要整体移动内部元素):链表的优点在于插入,删除元素时效率较高,但由于不 ...
- 原生JS实现二叉搜索树(Binary Search Tree)
1.简述 二叉搜索树树(Binary Search Tree),它或者是一棵空树,或者是具有下列性质的二叉树: 若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值: 若它的右子树不空,则右子 ...
- HDU - 3791 建立二叉搜索树
题意: 给定一个序列,下面又有n个序列,判断这个序列和其他序列是否为同一个二叉树(同一序列数字各不相同) 思路: 首先讲将一个序列建立成二叉搜索树,然后将其他序列也建立二叉搜索树,两个树进行前序遍历, ...
- 数据结构中的树(二叉树、二叉搜索树、AVL树)
数据结构动图展示网站 树的概念 树(英语:tree)是一种抽象数据类型(ADT)或是实作这种抽象数据类型的数据结构,用来模拟具有树状结构性质的数据集合.它是由n(n>=1)个有限节点组成一个具有 ...
- Java实现二叉搜索树的插入、删除
前置知识 二叉树的结构 public class TreeNode { int val; TreeNode left; TreeNode right; TreeNode() { } TreeNode( ...
- 手写AVL平衡二叉搜索树
手写AVL平衡二叉搜索树 二叉搜索树的局限性 先说一下什么是二叉搜索树,二叉树每个节点只有两个节点,二叉搜索树的每个左子节点的值小于其父节点的值,每个右子节点的值大于其左子节点的值.如下图: 二叉搜索 ...
- 斜堆(二)之 C++的实现
概要 上一章介绍了斜堆的基本概念,并通过C语言实现了斜堆.本章是斜堆的C++实现. 目录1. 斜堆的介绍2. 斜堆的基本操作3. 斜堆的C++实现(完整源码)4. 斜堆的C++测试程序 转载请注明出处 ...
随机推荐
- ionCube 安装
有些程序在php环境下运行需要安装ionCube Loader的扩展支持,得到如下提示 Site error: the ionCube PHP Loader needs to be installed ...
- C# 读取excel用户列表过滤一个月内未收到外部邮件已离职的员工
1.通过aspose.cells读取excel中的数据并添加到list中 //存储从excel中读取出来的数据 List<UserInfo> lst_userinfo = new List ...
- 使用PuTTy在CentOS下安装web.py与简单的文件传输
两周前,出于帮朋友忙的目的,尝试了一下微信公众号的菜单自定义与自动回复功能的实现,成了. 两周后,需要将代码转移至朋友新购的服务器上,发现基本操作全忘记了,麻瓜!所以记一笔,希望也能对大家也有帮助. ...
- 开博缘由 , 可点下看看 http://www.cnblogs.com/jshare
记录日常用中用到.遇到的问题 实现过程,仅供参考 不定时更新 ------------------- 之前看过一个文章,大概说的是开发和用到的过的代码,可以提取出一些代码片段,长时间下来,你会发现部分 ...
- Java快速入门-03-小知识汇总篇(全)
Java快速入门-03-小知识汇总篇(全) 前两篇介绍了JAVA入门的一系小知识,本篇介绍一些比较偏的,说不定什么时候会用到,有用记得 Mark 一下 快键键 常用快捷键(熟记) 快捷键 快捷键作用 ...
- androidcookie存储sqllite
/**声明一些数据库操作的常量*/ private static SQLiteDatabase mDatabase = null; private static final String DATA ...
- CentOS7 安装 JIRA 7.2.x 教程:下载、安装、汉化、破解
1.先看视频,参考着能装出个试用版来,不同的地方后面再做说明.JIRA 安装视频(Linux) http://www.confluence.cn/pages/viewpage.action?pageI ...
- golang开发不错的参考资料
https://golangbot.com/learn-golang-series/ https://gist.github.com/ivangabriele/1c552aadc247c0a2f256 ...
- POP动画[2]
POP动画[2] 1:定制控制器间的转场动画. 源码有点多-_-!! // // RootViewController.h // Animation // // Copyright (c) 2014年 ...
- VS2013 添加 ILDasm
1.找到ILDasm.exe文件: 打开C:\Program Files\Microsoft SDKs\Windows\v8.1A\bin\NETFX 4.5.1 Tools 2.vs外部工具添加 工 ...