堆排序时一种树形选择排序,它的特点是,在排序过程中,将r[1..n]看成是一个完全二叉树的顺序结构,利用完全二叉树中的父节点和左、右孩子结点之间的对应关系,在当前无序区中选择关键字最大的记录
堆的定义如下:n个关键字的序列{k1,k2,...kn}当且仅当满足以下关系时,称之为堆。
ki<=k(2*i) ki<=k(2*i+1) 或者 ki>=k(2*i) ki>=k(2*i+1)
堆排序主要解决两个问题:
1、如何按照堆定义构造一个初始堆
2、输出堆顶元素之后,如何重建堆
下面开始建造堆:
建造堆之前,先给出调整堆的代码,因为建造堆是建立在调整堆的基础上的。
//i 表示要调整第i个节点
//size 表示待排序的节点的个数
void HeapAdjust(int *a,int i,int size)
{
int leftChild=2*i;//左孩子在数组中的序号
int rightChild=2*i+1;//右孩子在数组中的序号
int tempindex=i;
if (i<=size/2)//只对非叶子节点进行调整
{
if (leftChild<=size && a[leftChild]>a[i])
{
tempindex=leftChild;
int temp=a[leftChild];
a[leftChild]=a[i];
a[i]=temp;
}
if (rightChild<=size && a[rightChild]>a[i])
{
tempindex=rightChild;
int temp=a[rightChild];
a[rightChild]=a[i];
a[i]=temp;
}
if (tempindex!=i)
{
HeapAdjust(a,tempindex,size);
}
}
}
下面建立一个堆
//建立一个堆
void BuildHeap(int *a,int size)
{
for (int i=size/2;i>=1;i--)
{
HeapAdjust(a,i,size);
}
}
进行堆排序
//堆排序
void HeapSort(int *a,int size)
{
BuildHeap(a,size);
for (int i=size;i>=1;i--)
{
int temp=a[1];
a[1]=a[i];
a[i]=temp;
HeapAdjust(a,1,i-1);
}
}
void main()
{
int a[11]={0,2,3,1,6,4,9,7,8,11,12};
HeapSort(a,10);
for (int i=1;i<=10;i++)
{
printf("%d\n",a[i]);
}
}