堆排序(英语:Heapsort)是指利用堆这种数据结构所设计的一种排序算法。堆是一个近似完全二叉树的结构,并同时满足堆的性质:即子结点的键值或索引总是小于(或者大于)它的父节点。
在堆的数据结构中,堆中的最大值总是位于根节点(在优先队列中使用堆的话堆中的最小值位于根节点)。堆中定义以下几种操作:
最大堆调整(Max Heapify):将堆的末端子节点作调整,使得子节点永远小于父节点
创建最大堆(Build Max Heap):将堆中的所有数据重新排序
堆排序(HeapSort):移除位在第一个数据的根节点,并做最大堆调整的递归运算
—以上来自百度百科
其中大顶堆和小顶堆,对应着算法的升序和降序。
本代码以大顶堆的升序为例:
程序函数:
void swap(int *a,int *b)
void heapify(int *a,int len,int i)//堆的维护,把父节点i的数值变成此堆最大的数。
void heapsort(int *a,int len)//堆排序入口
基本知识:(具体知识请参考数据结构-堆,二叉树)
每个下标为i的父节点:(i-1)/2;
每个下标为i的左孩子节点:2i+1
每个下标为i的右孩子节点:2i+2
完整代码:
#include<stdio.h>
void swap(int *a,int *b)
{
int temp;
temp=*a;
*a=*b;
*b=temp;
}
void heapify(int *a,int len,int i)//堆的维护,把父节点i的数值变成此堆最大的数。
{
int largest=i,lson=i*2+1,rson=i*2+2;
if(lson<len && a[largest]<a[lson])largest=lson;
if(rson<len && a[largest]<a[rson])largest=rson;
if(largest!=i)
{
swap(&a[i],&a[largest]);
heapify(a,len,largest);
}
}
/*
基本知识:
每个下标为i的父节点:(i-1)/2;
每个下标为i的左孩子节点:2*i+1
每个下标为i的右孩子节点:2*i+2
*/
void heapsort(int *a,int len)//堆排序入口
{
int i;
for(i=(len/2-1);i>=0;i--)//从最后一个父节点开始维护,建堆
{
heapify(a,len,i);
}
for(i=len-1;i>0;i--)//把最后的数和堆顶值交换,然后再进行堆的维护
{
swap(&a[0],&a[i]);//把堆顶最大的数和堆尾的数交换
heapify(a,i,0);//对堆顶进行维护,最大的数始终要在堆顶
}
}
int main()
{
int i;
int a[]={
3,5,1,-7,4,9,-6,8,10,4};
int len=(int)sizeof(a)/sizeof(int);
heapsort(a,len);
for(i=0;i<len;i++)printf("%3d",a[i]);
printf("\n");
return 0;
}