Heap Sort
一种基于选择排序思想,利用堆结构和二叉树的一些性质来完成数据排序的排序算法。
堆排序的关键是构造堆结构,准确而言,堆结构即是一个完全二叉树,树中的每一个节点对应原始数据的一个记录。每个节点应满足以下条件:
1)从小到大排序:要求非叶结点的数据要大于或等于其左、右子节点的数据。
2)从大到小排序:要求非叶节点的数据要小于或等于其左、右子节点的数据。
一个完整的堆排序需要反复经过两个步骤:构造堆结构和堆排序的输出。
构造堆结构过程:
对于一个非叶结点Ai,这里假定Ai的左子树与右子树已经进行了筛运算,即已构成堆结构;
1:比较Ai的左子树与右子树的最大值,将最大值放在Aj中。
2:将Ai的数据与Aj的数据进行比较,如果Ai大于Aj表示以Ai为根的子树已构成堆结构,便可以终止运算。
3:如果Ai小于Aj,则将Ai与Aj互换位置。
4:经过第三步后,可能会破坏以Ai为根的堆,因为此时Ai的值为原来的Aj。下面以Aj为根重复前面的步骤,直到满足堆结构的定义,即父节点大于子节点。这样一Aj为根的子树就被调整为一个堆结构。
堆排序的输出过程:
1:将堆结构的根节点放到数组的最后。
2:除最后一个节点外的其他节点重新执行前面的构造堆过程。
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#define SIZE 10
void HeapSort(int *a,int n)
{
int i,j,h,k;
int t;
for(i=n/2-1;i>=0;i--)
{
while(2*i+1<n)
{
j=2*i+1;
if((j+1)<n)
{
if(a[j]<a[j+1])
j++;
}
if(a[i]<a[j])
{
t=a[i];
a[i]=a[j];
a[j]=t;
i=j;
}
else{break;}
}
}
for(i=n-1;i>0;i--)
{
t=a[0];
a[0]=a[i];
a[i]=t;
k=0;
while(2*k+1<i)
{
j=2*k+1;
if((j+1)<i)
{
if(a[j]<a[j+1])
j++;
}
if(a[k]<a[j])
{
t=a[k];
a[k]=a[j];
a[j]=t;
k=j;
}
else{break;}
}
}
}
int main()
{
int i;
int shuzu[SIZE];
srand(time(NULL));
for(i=0;i<SIZE;i++)
shuzu[i]=rand()/1000+100;
printf("排序后的数组为:\n");
for(i=0;i<SIZE;i++)
printf("%d ",shuzu[i]);
printf("\n");
HeapSort(shuzu,SIZE);
printf("排序后的数组为:\n");
for(i=0;i<SIZE;i++)
printf("%d ",shuzu[i]);
printf("\n");
return 0;
}