排序


一、优先队列的基本概念?

优先队列是一种应该满足一下两种操作的数据结构:
1.插入(insert),显然这是往队列中存放元素的
2.删除最小者,体现出优先。

优先队列应用的简单举例:
1.操作系统的任务调度
2.排序(见第七章,即下周分享的内容)
3.用于贪婪算法(见第十章)的实现,该算法通过反复求出最小元来进行操作。

二、一些简单的实现

有几种明显的方法可以实现优先队列:
1.使用一个简单的链表,在表头以O(1)执行插入操作,并遍历该链表以O(N)删除最小元。
2.让链表保持排序状态,这样插入将是O(N)。

请思考对于一个队列来说,是使用1更好还是2更好。

3.使用二叉查查找树(左节点<根节点<右节点)。这样两种操作的平均时间复杂度都为O(logN),具体受树的深度(平衡度)影响。如果使用平衡二叉树,会保持树的平衡,但是维持树的平衡也需要相应时间。但是队列中不需要链表这种结构,下面来看看二叉查找树如何和队列合并。

三、二叉堆

3.1 二叉堆简介

我们将要使用的这种数据结构叫作二叉堆,它的使用对于优先队列的实现相当普遍,以至于当堆这个次不加修饰的用在优先队列的上下文时,一般都是指这种数据结构。类似于二叉查找树一样,对也有两个性质—1.结构性,2.堆序性。和AVL树类似,对堆的一次操作可能破环这两个性质中的一个,因此,堆的操作必须到堆的所有性质都被满足才能被终止。

3.2 二叉堆的两种性质

3.2.1 结构性质:

堆是一棵被完全填满的二叉树,有可能的例外是在底层,底层上的元素从左到右填入。这样的树称为完全二叉树。完全二叉树的高度为logN。完全二叉树十分规律所以可以使用数组表示,而不需要使用链。

完全二叉树与完满二叉树与AVL树 https://blog.csdn.net/weixin_38371369/article/details/109296260

在这里插入图片描述

对于任意位置i上的元素,其左儿子在2i的位置上,右儿子在2i+1的位置上。因此不需要链表,并且遍历操作极其简单。图中堆大小的界限为13个元素,该数组有一个位置0,后面将详细叙述。

3.2.2 堆序性质:

在一个堆中,对于每一个节点X,X的父亲中的关键字小于(或等于)X中的关键字。

为什么如此定义?
堆的主要操作为插入和找出最小元素,为保证快速(以O(1))找出最小元素所以最小元素应该在根上。但是保持堆序性和结构性,需要O(logN)。

3.3 二叉堆的基本操作

3.3.1 插入(insert):

使用一种叫上滤的策略,建立空穴,并找到元素应该插入的位置,如下图所示

在这里插入图片描述

为什么建立空穴?
保持二叉堆的结构性质----完全树。

3.3.2 删除最小元(deleteMin):

使用下滤策略,类似于上滤策略。删除最小元后,最后一个元素的位置一定会变动(保持结构性质),因此删除最小元后的主要操作是为最后一个元素找到应该存在的位置,如下图:
在这里插入图片描述

3.3.3 其他堆操作:

1.decreasrKey(降低关键字的值)
在某一个节点上将值降低,降低值可能破坏堆序性,需要上滤进行调整

2.increaseKey(增加关键字的值)
在某一个节点上增加值,需要下滤进行调整

3.delete(删除)
此操作通过先执行decreaseKey,然后再执行deleteMin。

4.buildHeap(构建堆)
一般的算法是将N项以任意顺序放入树种,保持结构性。之后通过对每个节点(从下往上)下滤来完成堆序性的维持。

四、d-堆(简单了解)

d-堆就是二叉堆,只不过2变成了d。比如4-堆。

思考d-堆和二叉堆相比的优缺点

队列太大的时候可以表现出b-tree的效果。插入时间减少为O(logdN)。删除最小项变得复杂,比较次数表多

五、左式堆

5.1 左式堆简介

左式堆也具有堆序性和结构性,其堆序性同其他堆。结构性上有所不同。对于左式堆的基本操作时间复杂度都为O(logN)

左式堆的结构性质:对于堆中的每一个节点X,做儿子的零路径长至少于右儿子的零路径长相等。

零路径长:任一节点X的零路径长(null path length)npl定义为X到一个不具有两个儿子的节点的最短路径长。任意节点的零路径长比它的各个儿子的零路径长的最小值大1.空节点的零路径长为-1.

在这里插入图片描述

5.2 左式堆基本操作

合并:递归的将最小根节点堆的右子树与另一个堆合并。若其不符合左式堆的结构性质则调换其左右儿子。递归的基准情形为判断左子树是否为空,为空则替换,不为空则判断右子树为空则替换之。之后判断是否符合左式堆的结构性,不符合则交换。最后计算零路径长。

删除最小项:删除根节点,之后将左子树和右子树合并。

插入:插入节点和左式堆的合并。

在这里插入图片描述
在这里插入图片描述

六、斜堆

6.1 左式堆基本操作

斜堆是具有堆序的二叉树,但不存在对树结构的限制。

斜堆的合并操作和左式堆基本一致,除了对左右儿子交换,因为斜堆没有结构限制。斜堆的交换是无条件的,除右路径上的所有节点的最大者不交换其左右儿子,剩下的都要交换。

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

七、二项队列

7.1 二项队列的结构

二项队列是二项树的集合(森林),每一棵堆序树都是一棵二项树,每个高度至多存在一棵。二项树的节点个数为2^k,其中k为二项树的高度。高度为0的二项树是一棵单节点树。二项队列的插入合并删除最小项的时间复杂度都为O(logN)

7.2 二项队列的操作

合并:保证合并后队列中没有一样高的树,相同高度的树合并时,以较小的根节点作为根,连接另一棵二项树。
在这里插入图片描述
在这里插入图片描述
插入:与另一个只有一棵高度为零的二项树的二项队列合并

删除最小项:找到最小根并删除,如删除后不满足二项队列结构,则合并。

7.2 二项队列的实现

在代码中如何表示二项队列的这种结构?类似于hashmap。

二项队列初始化一个数组,二项队列中的二项树每一个的根节点放到数组中。每一个链表的节点有两个属性,分别记录一个儿子节点和一个兄弟节点。这样即可完全描绘二项队列的数据结构,如下图。

在这里插入图片描述
二项队列种二项树合并代码大概是这样的,其中t1是小根的二项树

t2.nextSibLing=t1.leftChild;
t1.leftChild = t2;

八、标准库中的优先队列

java1.5以前,java类库中不存在对优先队列的支持。1.5出现了泛型类PriorityQueue。在该类中insert、findMin、deleteMin分别通过add、element、和remove表示。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值