堆排序算法——C语言

堆排序 

本次排序结果为非递减,采用的是大顶堆。

思想

小顶堆调整:

       假设输出堆顶元素之后,以堆中最后一个元素替代之,此时根节点的左右值比较,由于左子树根节点的值大于右子树的根节点的值且大于根节点的值,则将27和97交换,由于97替代了27之后破坏了右子树的堆,则需要进行上述相同的调整,直至叶子节点,此时堆顶为n-1个元素中的最大值,重复上述过程,将堆顶元素27和堆中最后一个元素97交换,得到新堆。

筛选:

从一个无序序列建堆的过程就是一个反复筛选过程。若将此序列看成是一个完全二叉树,则最后一个非终端点是第n/2个元素,由此筛选只需从第n/2个元素开始。

#include<stdio.h>

#define MAXSIZE 20		//数组大小

typedef int KeyType;	//关键字类型
typedef int InfoType;	//元素信息类型

//数组中元素的信息
typedef struct{
	KeyType key;		//元素排序的关键字
	InfoType otherinfo;	//元素信息
}RedType;
//数组的类型
typedef struct{
	RedType r[MAXSIZE+1];
	int length;
}SqList;
typedef SqList HeapType;	//堆类型
int count=0;
//初始化待排序列
void Init(SqList *L,int a[],int length)
{
	int i;
	RedType rt;
	for(i = 0;i < length;i++){
		rt.key = a[i];
		rt.otherinfo = i;
		L->r[i] = rt;
	}
	L->length = length;
}
//交换堆中元素
void swap(RedType *p,RedType *q){
	RedType temp = *p;
	*p = *q;
	*q = temp;
}

//打印堆
void print(HeapType *L){
	int j,k=1,l,m=1;
	for(l = L->length/2-(m++);l>=0;l--)
			printf("  ");
	for(j = 1;j < L->length;j++){
		
		printf("%d ",L->r[j].key);
		if(j == k){
			printf("\n");
			k=2*k+1;
			for(l = L->length/2-(m++);l>=0;l--)
			printf("  ");
		}
	}
}

//调整堆
void HeapAdjust(HeapType *H,int s,int m){
	int j;
	RedType rc;
	rc = H->r[s];
	for(j = 2*s;j<=m;j*=2){
		if(j < m && H->r[j].key < H->r[j+1].key)
			++j;
		if(rc.key >= H->r[j].key)
			break;
		H->r[s] = H->r[j];
		s = j;
	}
	H->r[s] =rc;
}
//堆排序
void HeapSort(HeapType *H){
	int i;
	for(i = (H->length-1)/2;i>0;--i)
		HeapAdjust(H,i,H->length-1);
	
	for(i = H->length-1;i>1;--i){
		printf("\n第%d趟排序后的堆:\n",++count);
		print(H);
		printf("\n");
		swap(&(H->r[1]),&(H->r[i]));
		HeapAdjust(H,1,i-1);
	}
}

int main(){
	HeapType L;
	int i;
	int a[9] = {0,49,38,65,97,76,13,27,49};
	Init(&L,a,9);
	printf("排序前:");
	for(i = 0;i < 9;i++){
		printf("%-2d ",L.r[i].key);
	}
	printf("\n下标号:");
	for(i = 0;i < 9;i++){
		printf("%-2d ",L.r[i].otherinfo);
	}
	printf("\n");
	print(&L);

	HeapSort(&L);

	printf("\n\n排序后:");
	for(i = 0;i < 9;i++){
		printf("%-2d ",L.r[i].key);
	}
	printf("\n下标号:");
	for(i = 0;i < 9;i++){
		printf("%-2d ",L.r[i].otherinfo);
	}
	printf("\n\n");
	return 0;
}

运行效果

运行效果

 

猜你喜欢

转载自blog.csdn.net/chenzhiwen1998/article/details/102791114