堆排序算法——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;
}

運行效果

運行效果

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章