堆排序算法

堆排序(Heap Sort)算法是基于选择排序思想的算法,其利用堆结构和二叉树的一些性质来完成数据排序。堆排序在某些场合具有广泛的应用。

堆排序算法

1、什么是堆结构
堆排序的关键是首先构造堆结构。那么什么是堆结构呢?堆结构是一种结构,准确地说是一个完全二叉树。在这个树中每个节点对应于原始数据的一个记录,并且每个结点应满足以下条件:

1)如果按照从小到大的顺序排序,要求非叶结点的数据要大于或等于其左、右子结点的数据。(大顶堆)
2)如果按照从大到小的顺序排序,要求非叶结点的数据要小于或等于其左、右子结点的数据。(小顶堆)

下面将以从小到大的顺序进行排序为例进行介绍。从堆结构的定义可以看出,对结点的左子结点和右子结点的大小没有要求,只规定父结点和子结点数据之间必须满足的大小关系。这样,如果要求按照从小到大的顺序输出数据,则堆结构的根结点为要求的最大值。

2、堆排序过程
一个完整的堆排序需要经过反复的两个步骤:构造堆结构和堆排序输出。下面首先分析如何构造堆结构。

构造堆结构就是把原始的无序数据按前面堆结构的定义进行调整。首先,需要将原始的无序数据放置到一个完全二叉树的各个结点中。然后,由完全二叉树的下层向上层逐层对父子结点的数据进行比较,使父结点的数据大于子结点的数据。这里需要使用“筛”运算进行结点数据的调整,直到所有结点最后满足堆结构的条件为止。筛运算主要针对非叶结点进行调整。

例如,对于一个非叶结点这里写图片描述,假定这里写图片描述的左子树和右子树均已进行筛运算,也就是说其左子树和右子树均已构成堆结构。对这里写图片描述进行筛运算,操作步骤如下:

1)比较这里写图片描述的左子树和右子树的最大值,将最大值放在这里写图片描述中。
2)将这里写图片描述的数据与这里写图片描述的数据进行比较,如果这里写图片描述大于等于这里写图片描述,表示以这里写图片描述为根的子树已构成堆结构。便可以终止筛运算。
3)如果这里写图片描述小于这里写图片描述,则将这里写图片描述这里写图片描述互换位置。
4)经过第(3)步后,可能会破坏以这里写图片描述为根的堆,因为此时这里写图片描述的值为原来的这里写图片描述。下面以这里写图片描述为根重复前面的步骤,直到满足堆结构的定义,即父结点数据大于子结点。这样,以这里写图片描述为根的子树就被调整为一个堆。

在执行筛运算时,值较小的数据将逐层下移,这就是其称为“筛”运算的原因。

下面通过一个实际的例子来分析构造堆结构的过程和堆排序输出的过程,以加深读者的理解。

假设有8个需要排序的数据序列67、65、77、38、97、3、33、49。构造堆结构的操作步骤如下:
1)首先将原始的数据构成一个完全二叉树。
堆排序算法_第1张图片
2)最后一个非叶结点为结点4,对该结点进行筛运算。该结点只有左子树,即结点8,并且38小于49。按照堆结构定义,使这两个结点互换位置。这样,结点4及其子结点构成一个堆结构。
堆排序算法_第2张图片
3)上述二叉树中倒数第2个非叶结点是结点3,对该结点进行筛运算。由于结点3的两个子结点中结点7的值较大,因此使结点3与结点7进行比较。因为77大于33,此时不需要进行互换,结点3及其子结点已经构成堆结构。
堆排序算法_第3张图片
4)上述二叉树中倒数第3个非叶结点是结点2,对该结点进行筛运算。由于结点2的两个子结点中结点5的值较大,因此使结点2与结点5进行比较。因为65小于97,此时需要将结点2与结点5互换数据。这样结点2及其子结点构成堆。
堆排序算法_第4张图片
5)上述二叉树中倒数第4个非叶结点是结点1,对该结点进行筛运算。由于结点1的两个子结点中结点2的值较大,因此使结点1与结点2进行比较。67小于97,因此将结点1与结点2互换数据。这时,因结点2的值已改变,需要重新对结点2及其子结点进行筛运算,因为有可能破坏了结点2与其子结点构成的堆结构。这样,结点1及其子结点构成堆结构。
堆排序算法_第5张图片

至此,便将原始的数据序列构造成一个堆结构。下面便可以进行堆排序输出,从而完成整个排序过程。操作步骤如下:
1)根据堆结构的特点,堆结构的根结点也就是最大值。这里按照从小到大排序,因此将其放到数组的最后。将结点8的值与结点1互换。
堆排序算法_第6张图片

2)结点8的值38换到根结点后,对除最后一个结点外的其他结点重新执行前面介绍的构造堆过程。此时,得到的堆结构。
堆排序算法_第7张图片

3)重复上述过程,取此时堆结构的根结点(最大值)进行交换,放在数组的后面。此时,结点1和结点7互换。
堆排序算法_第8张图片
4)然后重复将剩余的数据构造堆结构,取根结点与最后一个结点交换。
堆排序算法_第9张图片
堆排序算法_第10张图片
堆排序算法_第11张图片
堆排序算法_第12张图片
堆排序算法_第13张图片
堆排序算法_第14张图片
堆排序算法_第15张图片
5)再进一步执行堆排序输出,结点1和结点3互换。
堆排序算法_第16张图片
6)对最后的两个数据进行处理,得到最终的输出结果
堆排序算法_第17张图片
这样便完成了堆排序过程,得到的排序结果为:3、33、38、49、65、67、77、97

你可能感兴趣的:(算法)