堆排序-C语言实现

#include<stdio.h>
#include<malloc.h>
void Swap(int * a,int * b){
	int t=*a;
	*a=*b;
	*b=t;
}
void AdjustHeap(int a[],int location,int n){
	int key=a[location];
	for(int i=2*location;i<n;i*=2){
		if(i<n&&a[i]<a[i+1]) //找两者中最大的值
			i++;
		if(key>=a[i])//确定location的位置为i
			break;
		a[location]=a[i];
		location=i;
	}
	a[location]=key;
}
void CreateHeap(int a[],int n){
	for(int i=n/2-1;i>=0;i--){
		AdjustHeap(a,i,n);
	}
}
void HeapSort(int a[],int n){
	for(int i=n-1;i>=0;i--){
		Swap(a+i,a+0);
		AdjustHeap(a,0,i-1);
	}
}
void Print(int a[],int n){
	for(int i=0;i<n;i++){
		printf("%d ",a[i]);
	}
	printf("\n");
}
int main(){
	int n;
    while(scanf("%d",&n)!=EOF){
		int * data=(int *)malloc(sizeof(int));
		for(int i=0;i<n;i++){
			scanf("%d",data+i);
		}
		CreateHeap(data,n);
		HeapSort(data,n);
		Print(data,n);
		printf("\n");
	}
	return 0;
}

堆排序:堆排序为一种选择排序。

堆的定义:n个元素的序列,当且满足以下条件时称之为堆;

1)k_s>=k_2s 且k_s>=k_2s+1 或  2)k_s<=k_2s 且k_s<=k_2s+1

前者称之为大根堆,后者称之为小根堆

堆排序的步骤:

1)创建堆、2)交换堆顶和堆尾的元素、 3)调整堆 之后将2和3步重新进行n-1次循环;

调整堆:

1)保存起始位置s的值r[s]

2)   从r[2s]和r[2s+1]选取关键字较大的

若此关键字大小小于r[s]则此堆已经完成;反之交换此关键字与r[s],并将s位置置为当前值,调整堆直至到达叶子节点为止。

初建堆:

扫描二维码关注公众号,回复: 884981 查看本文章

由于叶子节点即为一个简单堆,所以对于该序列中([n/2]下取整-1)到1的节点进行调整即可。

堆排序:

交换堆顶与当前堆尾的值,并重新对堆进行调整,循环n-1次。

猜你喜欢

转载自blog.csdn.net/m0_37848958/article/details/78786759