原理:给定N个数,把这些数看成是一棵顺序存储的完整二叉树,然后将其调整为一个大顶堆(小顶堆),然后将堆的最后一个元素和堆顶元素交换,此时堆的最后一个元素就是最大(最小)的数;接着将前(N-1)个元素重新调整为一个大顶堆(小顶堆),再将堆顶元素和当前堆的最后一个元素交换得到次最大元素,重复该过程直到最后调整的堆只剩下一个元素为止,此时可得一个有序序列。
//堆排序
#include<stdio.h>
//交换两数
void Swap(int *a, int *b)
{
int temp;
temp = *a;
*a = *b;
*b = temp;
}
//建堆,保证父结点不大于子子节点
void AdjustMinHeap(int a[], int pos, int len)
{
int temp, child;
//父结点为temp = a[pos]
for (temp = a[pos];pos * 2 + 1 <= len;pos = child)
{
//子节点为child = pos*2+1
child = pos * 2 + 1;
//求出最小的子节点对应的下标
if (child<len && a[child]>a[child + 1])
++child;
//当父结点大于其最小的子节点的时候,交换两者
if (a[child] < temp)
a[pos] = a[child];
else
break;
}
a[pos] = temp;
}
void MyMinHeapSort(int array[], int len)
{
int i;
//找到第一个非叶子点建堆,len/2-1即为第一个非叶子的结点,并从此结点开始依次比较父结点和子节点的大小
for (i = len / 2 - 1;i >= 0;--i)
AdjustMinHeap(array, i, len - 1);
//依次交换堆的第一个元素和从第n个到第2个的位置,交换一次建堆一次
for (i = len - 1;i >= 0;--i)
{
Swap(&array[0], &array[i]);
AdjustMinHeap(array, 0, i - 1);
}
}
int main()
{
int array[] = { 1,4,7,9,2,3,5,8 };
int len = sizeof(array) / sizeof(array[0]);
MyMinHeapSort(array,len);
for (int i = 0;i < len;++i)
printf("%d ", array[i]);
printf("\n");
return 0;
}