实现优先队列结构主要是通过堆完成,主要有:二叉堆、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. 定义

零路径长度:到没有两个儿子的节点最短距离
左式堆:
1.一棵二叉树
2.零路径长:左儿子≧右儿子,父节点= min{儿子} +1(这条性质导致了左式堆的严重左偏)
 
零路径长度:
 
 

3.2. 操作:

(1) merge :

原则:根值大的堆与根值小的堆的右子堆合并(根值:根位置的元素值,并非零路径长度)
 
 
具体分三种情况(设堆H1的根值小于H2)
H1只有一个节点
H1根无右孩子
H1根有右孩子
 
(1.1).H1只有一个节点,若出现不满足:零路径长:左儿子≧右儿子,交换左右孩子。
 
(1.2).H1根无右孩子,若出现不满足:零路径长:左儿子≧右儿子,交换左右孩子。
 

(1.3).H1根有右孩子

1.初始状态,H1的根6,H2的根为8,将H2合并到H1。

2.将H1构造成根无右孩子的形式:

3.将元素10, merge到H2,要首先将H2构造成根无右孩子的形式,递归,merge,若出现不满足:零路径长:左儿子≧右儿子,交换左右孩子……

——》——》——》

4.

5.

3.3. 性质分析:

insert:merge
deleteMin:delete root,merge
时间复杂度:merge与右路径长度之和成正比;最坏O(logN)
缺点:交换需判断;维护零路径长

4. 斜堆

4.1. 定义

二叉树,根最小。由此可见:
 
 
 
特点:merge无条件交换。
 
时间复杂度:最坏O(N);最好Ω(1);平均O(logN)

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堆、左式堆、斜堆的更多相关文章

  1. 数据结构与算法——优先队列类的C++实现(二叉堆)

    优先队列简单介绍: 操作系统表明上看着是支持多个应用程序同一时候执行.其实是每一个时刻仅仅能有一个进程执行,操作系统会调度不同的进程去执行. 每一个进程都仅仅能执行一个固定的时间,当超过了该时间.操作 ...

  2. 树(二叉树 & 二叉搜索树 & 哈夫曼树 & 字典树)

    树:n(n>=0)个节点的有限集.有且只有一个root,子树的个数没有限制但互不相交.结点拥有的子树个数就是该结点的度(Degree).度为0的是叶结点,除根结点和叶结点,其他的是内部结点.结点 ...

  3. 自己动手实现java数据结构(六)二叉搜索树

    1.二叉搜索树介绍 前面我们已经介绍过了向量和链表.有序向量可以以二分查找的方式高效的查找特定元素,而缺点是插入删除的效率较低(需要整体移动内部元素):链表的优点在于插入,删除元素时效率较高,但由于不 ...

  4. 原生JS实现二叉搜索树(Binary Search Tree)

    1.简述 二叉搜索树树(Binary Search Tree),它或者是一棵空树,或者是具有下列性质的二叉树: 若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值: 若它的右子树不空,则右子 ...

  5. HDU - 3791 建立二叉搜索树

    题意: 给定一个序列,下面又有n个序列,判断这个序列和其他序列是否为同一个二叉树(同一序列数字各不相同) 思路: 首先讲将一个序列建立成二叉搜索树,然后将其他序列也建立二叉搜索树,两个树进行前序遍历, ...

  6. 数据结构中的树(二叉树、二叉搜索树、AVL树)

    数据结构动图展示网站 树的概念 树(英语:tree)是一种抽象数据类型(ADT)或是实作这种抽象数据类型的数据结构,用来模拟具有树状结构性质的数据集合.它是由n(n>=1)个有限节点组成一个具有 ...

  7. Java实现二叉搜索树的插入、删除

    前置知识 二叉树的结构 public class TreeNode { int val; TreeNode left; TreeNode right; TreeNode() { } TreeNode( ...

  8. 手写AVL平衡二叉搜索树

    手写AVL平衡二叉搜索树 二叉搜索树的局限性 先说一下什么是二叉搜索树,二叉树每个节点只有两个节点,二叉搜索树的每个左子节点的值小于其父节点的值,每个右子节点的值大于其左子节点的值.如下图: 二叉搜索 ...

  9. 斜堆(二)之 C++的实现

    概要 上一章介绍了斜堆的基本概念,并通过C语言实现了斜堆.本章是斜堆的C++实现. 目录1. 斜堆的介绍2. 斜堆的基本操作3. 斜堆的C++实现(完整源码)4. 斜堆的C++测试程序 转载请注明出处 ...

随机推荐

  1. 在Ubuntu 14.04.1 LTS 上安装gettext失败

    使用apt-get install -f,因为有额外的依赖.

  2. line-height和height的区别

    line-height 是指每行的高度, 假如定义p标签的行高为line-heigth:20px; 文字在浏览器中显示为一行时,这个p标签的高度会为20px,如果为两行,则p标签的高度为40px; l ...

  3. C# 求百分比并保留2位小数

    , b = ; decimal c = (decimal)a / b; , ); , )).ToString() + "%"; Console.WriteLine( - resul ...

  4. MongoDB for Java

    开发环境 操作系统:Windows7 IDE: MyEclipse Database: MongoDB 开发依赖库 bson-3.0.1.jar mongodb-driver-3.0.1.jar mo ...

  5. MAVLink Onboard Integration Tutorial

    MAVLink Onboard Integration Tutorial MAVLink is a header-only library, which means that you don't ha ...

  6. arcgis10.2 serverstyle 制作工具位置 小计

    跟9.3时候的套路还是一样的,只是工具已经放到了arcgis desktop的安装目录的bin文件夹下面. engine和developerkit都不附带该工具. 但是engine会附带一组默认的转换 ...

  7. Spring3实战第一章 Aop 切面 XML配置

    刚看spring3实战书籍第一章  切面以前没有关注过 现在看到了  随手试验一下 AOP AOP(Aspect Oriented Programming),即面向切面编程,可以说是OOP(Objec ...

  8. 4.Bootstrap基础总结

    一.Bootstrap 网格系统 二.Bootstrap 排版 三.Bootstrap 代码 四.Bootstrap 表格 五.Bootstrap 表单 六.Bootstrap 按钮 七.Bootst ...

  9. C# 试图加载格式不正确的程序。 (异常来自 HRESULT:0x8007000B)

    C# 在调用C++dll时,可能会出现 :试图加载格式不正确的程序. (异常来自 HRESULT:0x8007000B)这个错误. 一般情况下是C#目标平台跟C++dll不兼容,64位跟32位兼容性问 ...

  10. Java BigDecimal初探

    更新时间:2016-03-17 一.引言 <Effactive Java>中有这样的描述:float和double类型的主要设计目标是为了科学计算和工程计算.他们执行二进制浮点运算,这是为 ...