什么是堆?堆排序又是什么?

此堆非彼堆。常见的「 堆 」的概念是指一种数据按序排列的数据结构,只能在其一端对数据进行插入和删除操作。

另一种就是「 堆内存 」了,其与「 栈内存 」的不同在于:

1. 栈内存由操作系统分配,堆则由程序员自己决定。

2. 栈的大小是固定的,只要栈的剩余空间大于所申请的空间,系统将为程序提供内存,否则将报异常提示栈溢出。堆的大小则受限于系统的有效虚拟内存。

3. 栈的空间有系统决定何时释放,堆需要程序员自己决定。

4. 堆需要人为通过 new ,delete 等操作分配,释放内存,容易产生碎片,但方便使用。栈的内存分配由系统自动管理。

简单的理解就是:使用「 栈内存 」就如同我们去饭馆吃饭,程序员只负责点单和享用美食,而用餐前的洗菜,切菜等和用餐后的餐具收拾,清洗等事务由饭馆负责。使用「 堆内存 」就好像我们自己动手料理,虽然需要自己收拾垃圾等,但自己动手做出来的更适合自己的口味,而且*度大。

咳咳,跑题了,重新回到我们的话题中来。堆排序中的「 堆 」可看成是一棵完全二叉树,树中所有非终端结点的值均不大于(或不小于)其左,右孩子的结点的值,对应的堆称为「 小顶堆 」(或「 大顶堆 」)。

以大顶堆为例:

建堆(筛选法):先把序列建成堆(此时是无序的)。因为序列视为一棵完全二叉树,其最后一个非终端结点是第「n / 2」(向下取整)个元素,以其为根,与其子结点构成一棵树。从这个元素开始与其左右子树根结点的最大值比较,若左右子树根结点的最大值(假设为左子树)较小,不进行任何操作,否则左子树根结点上移,原根节点下沉替换原左子树结点。若交换后的左子树结点有子树则再进行一次比较,直至交换后的根节点没有子树或原根节点的值大于其左右子树根节点的值顺序对「 n / 2 」(向下取整)前的元素进行同样的操作,最后得到一个大顶堆(自下而上调整)。

以序列 { 1, 3, 4, 5, 7, 2 ,6, 8, 0 }为例,整个建堆过程如下:

什么是堆?堆排序又是什么?

排序(非递减):将最大值(即堆顶元素)与最后一个元素交换(下标为「 n 」),再将序列前 n - 1个元素重新调整为堆。如此反复至层次遍历堆时输出有序 。过程如图:

什么是堆?堆排序又是什么?

删除堆顶元素后,最后一个元素成为新的堆顶,重新建堆(自上而下调整)。如,删除堆顶元素「 8 」,过程如下:

什么是堆?堆排序又是什么?

插入元素:将插入的元素放在最后,进行排序(非递减)。




              




现在应该对堆排序有了一定的了解,那么接下来做几道题巩固一下知识吧。

1.

对于序列( 12 , 13 , 11 , 18 , 60 , 15 , 7 , 19 , 25 , 100 ),用筛选法建堆,必须从值为 ________ 的数据开始建初始堆。

A. 100     B. 12      C. 60      D. 15

2.

将关键字序列 { 50,40,95,20,15,70,60,45,80 } 调整成一个小根堆,堆结构是 { 15,20,60,45,40,70,95,50,80 }()。

A. 对        B. 错

3.

{ 0、2、1、4、3、9、5、8、6、7 } 是以数组形式存储的最小堆,删除堆顶元素0后的结果是()

A. { 2、1、4、3、9、5、8、6、7 }        B.{ 1、2、5、4、3、9、8、6、7 }

C. { 2、3、1、4、7、9、5、8、6 }        D.{ 1、2、5、4、3、9、7、8、6 }

4.

已知关键字序列 5 , 8 , 12 , 19 , 28 , 20 , 15 , 22 是小根堆(最小堆),插入关键字 3 ,调整后得到的小根堆是 ()。

A. { 3,5,12,8,28,20,15,22,19 }

B. { 3,5,12,19,20,15,22,8,28 }

C. { 3,8,12,5,20,15,22,28,19 }

D. { 3,12,5,8,28,20,15,22,19 }

5.

在用堆排序算法排序时,如果要进行增序排序,则需要采用"大根堆"。()

A. 对        B . 错

6.

层次遍历初始堆可以得到一个有序的序列。( )

A.  对        B. 错

什么是堆?堆排序又是什么?

答案:CAD      AAB