算法与数据结构——排序(六)堆排序
在前面的排序算法里面,我们发现每次找到一个最小的数都要进行很多次的比较,比如在n个数里面,我们如果想要找到最小的数,那么就需要比较 n-1次,那么我们想,能不能减少每次比较的次数呢。 其实发现是可以的,在前面的简单选择排序算法里面,我们每次找到最小的数后,剩余的一些数,其实有的是已经经过比较了的,所以在我们寻找第二小的数的时候,完全可以利用第一次的比较结果,但是由于我们没有把第一次比较的结果记录下来,所以我们在后面的比较过程中用不到,那么我们会想,能不能想办法把第一次比较的结果保存下来呢。办法肯定是有的,这就是今天我们要学习的堆排序。 那么什么是堆排序呢,我们首先要弄清楚什么是堆。看下面的两个图,它们都是堆: 通过图我们可以看出,它们的根结点,要么比他们的左右孩子都大,要么比他们的左右孩子都小。这就是堆。具体的定义就是: 堆是具有以下性质的完全二叉树,每个结点的值都大于或者等于其左右孩子结点的值,叫做大顶堆,每个结点的值都小于或者等于其左右孩子结点的值,叫做小顶堆。由二叉树的一个性质,我们可以知道,一个完全二叉树,如果它的根结点位置是i,那么它左孩子位置就是2i,右孩子位置就是2i+1,所以大顶堆可以定义为ki>=k2i并且ki>=k2i+1,小顶堆的符号刚刚相反。 把堆进行层序遍历装入数据组,是如下结果: 堆排序算法,就是把一个序列构造成一个大顶堆(此处以大顶堆为例)