堆的概念:堆是一个完全二叉树,树中每个结点对应于一个数据,每个结点应满足以下条件:非叶结点的数据大于或等于其左右孩子结点的数据。左右孩子结点的大小没有要求。从堆的概念中可以看出根结点的值应为最大值。
利用堆排序的基本思想:
(1)将无序的数据构成堆,
(2)利用堆排序(即将堆中的数据有序输出);
因此,堆排序的俩个难点步骤即是生成堆及利用堆排序。以下详述俩个步骤的详细过程。
利用堆排序的具体过程:
1.构成堆
构成堆主要使用一种称为“筛“的运算,从二叉树的底层逐层对结点数据进行比较,进行调整,使之满足堆的条件。
筛运算是对非叶结点进行的,当对某结点进行筛运算时,比它编号大的非叶结点都已经过筛运算,因此筛运算是在其左右子树均为堆的基础上实现的。
以对结点Ai进行筛运算为例:
(1)确定Ai俩个子树中的最大值,放在Aj中;
(2)将Ai的数据与Aj作比较,如果Ai>=Aj,满足堆的定义,筛运算完毕;
(3)若Ai<Aj,则交换,互换后,可能会破坏原先形成的堆,接着再以Aj为根重复前面步骤,直至父节点大于子节点,或子节点为空。
2.利用堆排序
形成堆后,根节点的值当为整个二叉树中最大,按序输出时,需将其放在数组最后。根据这个规律,输出堆中数据的具体过程为:
(1)取根节点放在数组最后,
(2)重新执行筛运算,重新构成堆,此时应将最后一个节点排除在外,
(3)重复该过程,逐步从根节点取出最大值,放入数组最后,再对剩余节点重新构成堆
c++代码实现
1.堆构造部分HeapAdjust
2.堆排序部分HeapSort
3.测试主函数TestMain
HeapAdjust
HeapSort