什么是堆排序
堆排序是指用堆这种数据结构所设计的排序算法
图片借鉴于https://blog.csdn.net/sinat_31275315
堆排序思路
1.首先把要排序的数组变成大堆或者是小堆,要排成升序建成小堆,要排成降序建成大堆
小堆:根的左右子树均为小堆(逻辑结构上)
大堆:根的左右子树均为大堆(逻辑结构上)
大堆和小堆实际结构(物理结构)是数组
在本土中最后一个节点是9,下标是4,所以双亲节点为(4-1)/2=1。
由此可知我们要从6开始一次往前向下调整
下标为1处节点向下调整结束后,从(1-0)/2=0,也就是跟节点开始向下调整
调整结束后数组就已经变成了大堆或者小堆
2.把堆顶数据和堆尾数据交换,然后堆的个数减一,减去的元素用虚线表示(并不是从数组中删除而是从堆中删除,把堆的个数减一就相当于从堆中删除)
3.向下调整
堆顶和堆尾的数据交换后堆便不是大堆或者小堆了,所以要向下调整
4.按照2,3步骤循环进行
最终数组变成如下所示
代码
#include <stdio.h>
void swap(int* hp1, int* hp2)
{
int temp = *hp1;
*hp1 = *hp2;
*hp2 = temp;
}
void AdjustDown(int* a, int n, int parent)
{
int child = parent * 2 + 1;
while (child < n)
{
if (child + 1 < n && a[child + 1] > a[child])
{
child++;
}
if (a[child] > a[parent])
{
swap(&a[parent], &a[child]);
parent = child;
child = parent * 2 + 1;
}
else
{
break;
}
}
}
void HeapSort(int* a,int n)
{
for (int i = (n - 1) / 2; i >= 0; i--)
{
AdjustDown(a, n, i);
}
for (int end = n-1; end >=0; end--)
{
swap(&a[end], &a[0]);
AdjustDown(a, end, 0);
}
}
void HSPrint(int* a,int n)
{
for (int i = 0; i < n; i++)
{
printf("%d ", a[i]);
}
}
int main()
{
int a[] = { 70,56,30,25,15,10,75 };
HeapSort(a, sizeof(a) / sizeof(a[0]));
HSPrint(a, sizeof(a) / sizeof(a[0]));
return 0;
}