#include<stdio.h>//堆排序
#define leftchild(i) (2*i+1)
void percdown(int a[],int i,int n){
int child;
int temp;
for(temp=a[i];leftchild(i)<n;i=child){
child=leftchild(i);
if(child!=n-1&&a[child+1]>a[child])
child++;
if(temp<a[child])
a[i]=a[child];
else
break;
}
a[i]=temp;
}
void swap(int *x,int *y){
int t;
t=*x;
*x=*y;
*y=t;
}
void heapsort(int a[],int n){
int i;
for(i=n/2;i>=0;i--)
percdown(a,i,n);//有这个数组建立一个堆
for(i=n-1;i>0;i--){
swap(&a[0],&a[i]);
percdown(a,0,i);//交换最后一个数与第一个数,然后对剩下的数进行堆排序
}
}
int main(){
int n;
scanf("%d",&n);
int i;
int a[n];
for(i=0;i<n;i++){
scanf("%d",&a[i]);
}
heapsort(a,n);
for(i=0;i<n;i++)
printf("%d ",a[i]);
return 0;
}
堆排序的具体实现步骤
#include<stdio.h>//堆排序,输出了每一步的排序
#define leftchild(i) (2*i+1)
void percdown(int a[],int i,int n){//用数组a[ ]下滤建立一个堆
int child;
int temp;
for(temp=a[i];leftchild(i)<n;i=child){//孩子要小于总结点
child=leftchild(i);
if(child!=n-1&&a[child+1]>a[child])
child++;
if(temp<a[child])
a[i]=a[child];
else
break;
}
a[i]=temp;
}
void swap(int *x,int *y){//swap函数,交换两个数
int t;
t=*x;
*x=*y;
*y=t;
}
void heapsort(int a[],int n){
int i,j;
for(i=n/2;i>=0;i--)//从n/2开始,是因为从最大的父节点开始比较
percdown(a,i,n);//有这个数组建立一个堆
for(i=n-1;i>0;i--){
swap(&a[0],&a[i]);
percdown(a,0,i);//交换最后一个数与第一个数,然后对剩下的数进行堆排序
for(j=0;j<n;j++){//验证每一步排序
printf("%d ",a[j]);
}
printf("\n");
}
}
int main(){
int n;
scanf("%d",&n);
int i;
int a[n];
for(i=0;i<n;i++){
scanf("%d",&a[i]);
}
heapsort(a,n);
return 0;
}
一个简单的例子
堆排序不是稳定的排序,由下面这个例子可知a【3】最后变为了a【6】(下面图上写错了,应该是a【6】)