首页 存档 技术 查看内容

五张图带你体会堆算法

2018-3-30 13:00 |来自: 互联网 336 0

摘要: 五张图带你体会堆算法 来自:NoMasp柯于旺-CSDN博客 链接:http://blog.csdn.net/nomasp/article/details/46292633 编辑:Gemini 什么是堆 堆(heap),是一类特殊的数据结构的统称。它通常被看作一棵树的数组对象 ...

五张图带你体会堆算法


来自:NoMasp柯于旺-CSDN博客

链接:http://blog.csdn.net/nomasp/article/details/46292633

编辑:Gemini


什么是堆

堆(heap),是一类特殊的数据结构的统称。它通常被看作一棵树的数组对象。在队列中,调度程序反复提取队列中的第一个作业并运行,因为实际情况中某些时间较短的任务却可能需要等待很长时间才能开始执行,或者某些不短小、但很重要的作业,同样应当拥有优先权。而堆就是为了解决此类问题而设计的数据结构。

二叉堆是一种特殊的堆,二叉堆是完全二叉树或者近似完全二叉树,二叉堆满足堆特性:父节点的键值总是保持固定的序关系于任何一个子节点的键值,且每个节点的左子树和右子树都是一个二叉堆。

当父节点的键值总是大于任何一个子节点的键值时为最大堆,当父节点的键值总是小于或等于任何一个子节点的键值时为最小堆。

为了更加形象,我们常用带数字的圆圈和线条来表示二叉堆等,但其实都是用数组来表示的。如果根节点在数组中的位置是1,第n个位置的子节点则分别在2n和2n 1位置上。

如下图所描的,第2个位置的子节点在4和5,第4个位置的子节点在8和9。所以我们获得父节点和子节点的方式如下:

PARENT(i)

1 return 小于或等于i/2的最大整数

LEFT-CHILD(i)

1 return 2i

RIGHT-CHILD(i)

1 return 2i 1

假定表示堆的数组为A,那么A.length通常给出数组元素的个数,A.heapsize表示有多少个堆元素存储在该数组中。这句话略带拗口,也就是说数组A[1...A.length]可能都有数据存放,但只有A[1...A.heapsize]中存放的数据才是堆中的有效数据。毫无疑问0≤A.heapsize≤A.length。

最大堆除了根以外所有结点i都满足:A[PARENT(i)]≥A[i]。

最小堆除了根以外所有结点i都满足:A[PARENT(i)]≤A[i]。

一个堆中结点的高度是该结点到叶借点最长简单路径上边的数目,如上图所示编号为4的结点的高度为1,编号为2的结点的高度为2,树的高度就是3。

包含n个元素的队可以看作一颗完全二叉树,那么该堆的高度是Θ(lgn)。


通过MAX-HEAPIFY维护最大堆


程序中,不可能所有的堆都天生就是最大堆,为了更好的使用堆这一数据结构,我们可能要人为地构造最大堆。

如何将一个杂乱排序的堆重新构造成最大堆,它的主要思路是:

从上往下,将父节点与子节点以此比较。如果父节点最大则进行下一步循环,如果子节点更大,则将子节点与父节点位置互换,并进行下一步循环。注意父节点要与两个子节点都进行比较。

子节点更大,则将子节点与父节点位置互换,并进行下一步循环。注意父节点要与两个子节点都进行比较。


如上图说描述的,这里从结点为2开始做运算。先去l为4,r为5,将其与父节点做比较,发现左子节点比父节点更大。因此将它们做交换,设4为最大的结点,并继续以结点4开始做下一步运算。

因此可以给出伪代码如下:

MAX-HEAPIFY(A,i)

1 l=LEFT-CHILD(i)

2 r=RIGHT-CHILD(i)

3 if l

声明:文章版权归原作者所有 部分文章转自互联网 如有侵权请联系 [邮箱地址] 删除

路过

雷人

握手

鲜花

鸡蛋

相关分类

返回顶部