堆排序算法详细总结—配图说明
在计算机科学中,二叉树是每个节点最多有两个子树的树结构。通常子树被称作“左子树”
(left subtree)和“右子树”(right subtree)。二叉树常被用于实现二叉查找树和二叉堆。二叉查
找树是按照左子结点大于(小于)根节点大于(小于)右子结点进行构建的树,二叉堆则无此构
建顺序要求,但也要求不能进行左后孩子互换。
1、 堆排序定义
n 个关键字序列 Kl,K2,…,Kn 称为堆,当且仅当该序列满足如下性质(简称为堆性质):
(1) ki≤K2i 且 ki≤K2i+1 或 (2)Ki≥K2i 且 ki≥K2i+1(1≤i≤n/2 ) 【注意:左右孩子节点之间比较并
没有大小要求,且注意下标号,在实际用数组存储时有变化】
若将此序列所存储的向量 R[1..n]看做是一棵完全二叉树的存储结构,则堆实质上是满足如下性
质的完全二叉树:树中任一非叶结点的关键字均不大于(或不小于)其左右孩子(若存在)结点的关
键字。
【例】关键字序列(10,15,56,25,30,70)和(70,56,30,25,15,10)分别满足堆性质(1)和
(2),故它们均是堆,其对应的完全二叉树分别如小根堆示例和大根堆示例所示。
2、大根堆和小根堆
根结点(亦称为堆顶)的关键字是堆里所有结点关键字中最小者的堆称为小根堆。
根结点(亦称为堆顶)的关键字是堆里所有结点关键字中最大者,称为大根堆。
注意:
①堆中任一子树亦是堆。
②以上讨论的堆实际上是二叉堆(Binary Heap),类似地可定义 k 叉堆。
3、堆排序特点
堆排序(HeapSort)是一树形选择排序。
堆排序的特点是:在排序过程中,将 R[l..n]看成是一棵完全二叉树的顺序存储结构,利用完全二
叉树中双亲结点和孩子结点之间的内在关系【参见二叉树的顺序存储结构】,在当前无序区中选
择关键字最大(或最小)的记录。
4、堆排序与直接插入排序的区别
直接选择排序中,为了从 R[1..n]中选出关键字最小的记录,必须进行 n-1 次比较,然后在 R[2..n]
中选出关键字最小的记录,又需要做 n-2 次比 较。事实上,后面的 n-2 次比较中,有许多比较
可能在前面的 n-1 次比较中已经做过,但由于前一趟排序时未保留这些比较结果,所以后一趟排
序时又重复执行 了这些比较操作。
堆排序可通过树形结构保存部分比较结果,可减少比较次数。
5、堆排序
堆排序利用了大根堆(或小根堆)堆顶记录的关键字最大(或最小)这一特征,使得在当前无序区中
选取最大(或最小)关键字的记录变得简单。
1 /*
2 堆排序
3 (1)用大根堆排序的基本思想
4 ① 先将初始文件 R[1..n]建成一个大根堆,此堆为初始的无序区
5 ② 再将关键字最大的记录 R[1](即堆顶)和无序区的最后一个记录 R[n]交换,
6 由此得到新的无序区 R[1..n-1]和有序区 R[n],且满足 R[1..n-1].keys≤R[n].key
7 ③ 由于交换后新的根 R[1]可能违反堆性质,故应将当前无序区 R[1..n-1]调整为堆。