堆排序(Heap Sort)是一种选择排序,每趟从待排序列中选出最大或者最小的关键字。
首先来解释下什么叫堆?
堆定义:n个元素的序列{k1,k2,…,kn}当且仅当满足下关系时,称之为堆。
或 其中 。
堆排序,也是对满足堆条件的序列的排序。那么对一个无序的序列进行堆排序之前,首先要将待排序序列转换成堆。如何将无序序列转换成堆?
若将满足堆条件的序列看做是完全二叉树存储结构,那么这颗完全二叉树就满足以下条件:某根结点的值大于等于其左右子节点的值,或者根结点的值小于等于左右子节点值。根据这个特点,将无序序列转换成堆的思路就有了。即是:将不满足此条件的完全二叉树转换成满足此条件的完全二叉树。下面以根堆最大为例描述具体的实现方法。
首先从第 个元素开始,查看它是否大于等于左右子节点,若是则查看 -1个元素;若不是则将这个元素与其左右结点中较大的元素进行互换。
无序序列转换成了堆,那么如何对堆进行排序呢?
堆排序是一种选择排序,也就是说每趟从数列中选择一个最大或者最小的元素。那么在堆中,根结点就是序列中最大或者最小的元素。那么对堆进行排序首先就是将序列的第一个元素也即是根结点元素与最后一个元素进行交换,序列长度减一。那么现在最后一个元素就称为了根结点元素,这必然打乱了原来的堆,那么就需要原有的堆进行重新排列,形成一个新的堆。查看新的根结点r是否大于等于其左右子节点,若不满足则与其中较大者m互换,互换了之后r是m的子结点,但是若此时的r还有子节点的话,还需要查看其是否大于等于其子节点。
注意:上述描述中讲到完全二叉树,并不是说明待排序的序列需要用二叉树的结构来存储。而是,将待排序的序列看成是一颗完全二叉树的顺序存储结构。
具体实现代码: