在上一期中我们了解了什么是堆,这里我们简单总结一下,堆就是完全二叉树的顺序存储(这里哦我们也将满二叉树看成了完全二叉树)。
今天中,我们要来了解基于堆的一种排序,堆排序,也就是让堆中的数据变得有序
我们先来纠正一个误区,以小堆为例,有人认为,当我们的堆为小堆的时候,这时候我们的堆就是有序的,这种说法是错误的。
观察以下的一个堆,虽然它满足小堆,但是它并不是有序的 1 4 3 7 6
究其本质,我们说过,大小堆只是将父结点和孩子结点的关系进行了说明,但是并没有将兄弟结点的关系进行说明。
那么我们要怎样实现我们的堆排序呢???
这里我们以升序排列为例子。
首先我们先要创建大堆,这里很多人可能会问,为什么我们排列升序要创建大堆呢?
我们先来看看,如果创建小堆会怎么样:
创建小堆后,我们确实可以得到最小的值,但是我们会发现那1的孩子结点4和3就没有办法调整过来了。
我们再来看看创建大堆:
我们可以得到最大的值,所以升序时我们只需要通过交换将它放在数组的尾部,之后将堆顶的元素向下调整(排除最后一个元素)得到第二大的数字,以此类推,不断交换,最后我们就可以调整成升序排序。
交换7和3
之后让3进行向下调整
3向下调整过的结果,之后重复以上的步骤就可以了
下面是具体的代码的实现:
下面是代码:
void HeapSort(int arr[],int n)
{
for (int i = 1; i < n; i++)
{
AdjustUp(arr, i);//先使用向上调整创建大堆
}
int end = n - 1;
while(end > 0)
{
swap(&arr[0], &arr[end]);
AdjustDown(arr, end, 0);//之后不断向下调整找到第二大的数
end--;
}
}
谢谢观看!!!