目录
基础+前情提要
1. 对于堆排序来说,逻辑结构是完全二叉树(就是靠左的那颗书树)。
2. 关于堆排序,最重要的两个操作就是heapinsert和heapify。堆排序就是基于这两个操作实现的。
heapinsert
该操作就是将逐个输入的序列按照大根堆进行组织。
(大根堆就是根大,父节点大于儿子节点的情况。)
实现思路:
由于输入的序列是一个数组,每个数都有自己的下标,因此我们可以通过该下标找到该数的父节点( (i-1)/2 )和子节点(左:2i+1;右:2i+2)。
通过对该数与该数的父节点的比较,我们将更大的数放在父节点就可以得到大根堆。
heapify
就是当已经是大根堆的数组,现在有的值被改变了,需要重新调整来实现大根堆。(注意前提是该数的父节点部分不用改变,只考虑它和它子树的情况)
该思路就是从上至下,依次与自己的最大的孩子节点进行比较,如果小于自己的最大的孩子就和孩子换位置。如果自己的位置就是最大的或者到达了没有左子树(完全二叉树,靠左)的情况,就结束。
堆排序
堆排序的思路就是利用上述两个方法进行。
等同于一个数组堆的部分为0,逐步扩大范围(长度用heapsize表示,初始情况其值为0)。
首先利用heapinsert函数组织大根堆,得到这样一个序列之后,数组位置为0的数就是大根堆的最大值,因此我们把这个值”弹出“(这个操作指的是,将数组中第一个和最后一个位置的数值交换,同时heapsize--。也就是把最大值放在最后一位上,同时它的位置被确定后,就不管它了)
然后从0位置开始做heapify,也就是重新给这个数找位置,heapify结束后,新的根的位置同样是剩下序列的最大值,因此我们把这个值”弹出“。
重复上述步骤,最后得到的就是有序排列。