C++編程練習(13)----“排序算法 之 堆排序“

堆排序

堆是具有下列性質的完全二叉樹每個結點的值都大於或等於其左右孩子結點的值,稱爲大頂堆(也叫最大堆);或者每個結點的值都小於或等於其左右孩子結點的值,稱爲小頂堆(也叫最小堆)。

最小堆和最大堆如下圖示:


可以發現:根結點一定是堆中所有結點最大(小)者

堆排序的基本思想(以大頂堆爲例):將待排序的序列構成一個大頂堆。此時,整個序列的最大值就是堆頂的根結點。將它移走(其實就是將其與堆數組的末尾元素交換,此時末尾元素就是最大值),然後將剩餘的 n-1 個序列重新構成一個堆,這樣就會得到 n 個元素中的次大值。如此反覆執行,便能得到一個有序序列了。


堆排序的思想用例圖解釋如下:

1. 初始最小堆的建立過程(自下向上逐步調整爲最小堆)



具體代碼如下:

1、排序前的一些準備工作,建立合適的排序需要的結構。

/********* 排序用到的結構  頭文件sort_struct.h ************/
#define MAXSIZE 100 //要排序數組個數最大值

class SqList{
public:
	int r[MAXSIZE+1];
	int length;
};

/* 交換L中數組r下標爲i和j的值 */
void swap(SqList *L, int i, int j)
{
	int temp = L->r[i];
	L->r[i] = L->r[j];
	L->r[j] = temp;
}

/* 顯示數組內容 */
void showSqList(SqList *L)
{
	for(int i=1;i<=L->length;i++)
		std::cout<<L->r[i]<<"  ";
	std::cout<<std::endl;
}
2、編寫主文件,實現排序與測試。

/********* C++堆排序算法 ************/
#include<iostream>
#include<time.h>
#include"sort_struct.h"
using namespace std;

/* 本函數調整L->r[s]的關鍵字,使L->r[s...m]成爲一個大頂堆 */
void HeapAdjust(SqList *L,int s,int m)
{
	int temp,j;
	temp = L->r[s];
	for(j=2*s;j<=m;j*=2)	//沿關鍵字較大的孩子結點向下篩選
	{
		if(j<m && L->r[j]<L->r[j+1])
			++j;	//j爲關鍵字中較大的孩子結點的下標
		if(temp>=L->r[j])		//如果關鍵字均大於孩子結點,跳出
			break;
		L->r[s] = L->r[j];	//否則交換關鍵字與較大孩子結點的內容
		s = j;
	}
	L->r[s] = temp;		//完成插入
}

/* 對順序表L進行堆排序 */
void HeapSort(SqList *L)
{
	int i;
	for (i=L->length/2;i>0;i--)	//把L中的r構建成一個大頂堆
		HeapAdjust(L,i,L->length);
	
	for (i=L->length;i>1;i--)
	{
		swap(L,1,i);	//將堆頂記錄和當前未經排序子序列的最後一個記錄交換
		HeapAdjust(L,1,i-1);	//將L->r[1...i-1]重新調整爲大頂堆
	}
}



int main()
{
	int num[] = {0,50,30,25,15,84,56,34,99,54,111,24,43,6,62,124};
	SqList *L = new SqList;
	L->length = sizeof(num)/sizeof(int)-1;
	for(int i=1;i<=L->length;i++)
		L->r[i] = num[i];
	cout<<"排序前:";
	showSqList(L);
	clock_t start = clock();
	HeapSort(L);
	clock_t end = clock();
	double time = ((double)(start-end)) / (double)CLOCKS_PER_SEC * 1000;
	cout<<"排序後:";
	showSqList(L);
	cout<<"耗時:"<<time<<"ms"<<endl;
	return 0;
}

運行結果如下:

由於待排序樣本太少,耗時顯示爲0。

發佈了49 篇原創文章 · 獲贊 10 · 訪問量 8萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章