經典算法:堆排序

 堆排序

堆排序是利用堆的性質來進行排序的一個算法。


一、堆

  堆(英語:heap)是計算機科學中一類特殊的數據結構的統稱。堆通常是一個可以被看做一棵樹的數組對象。堆總是滿足下列性質:
  • 堆中某個節點的值總是不大於或不小於其父節點的值;
  • 堆總是一棵完全二叉樹。
  將根節點最大的堆叫做最大堆或大根堆,根節點最小的堆叫做最小堆或小根堆。常見的堆有二叉堆、斐波那契堆等。
  堆的定義如下:n個元素的序列{k1,k2,ki,…,kn}當且僅當滿足下關係時,稱之爲堆。
(ki <= k2i,ki <= k2i+1)或者(ki >= k2i,ki >= k2i+1), (i = 1,2,3,4...n/2)
若將和此次序列對應的一維數組(即以一維數組作此序列的存儲結構)看成是一個完全二叉樹,則堆的含義表明,完全二叉樹中所有非終端結點的值均不大於(或不小於)其左、右孩子結點的值。由此,若序列{k1,k2,…,kn}是堆,則堆頂元素(或完全二叉樹的根)必爲序列中n個元素的最小值(或最大值)。


  以上資料摘自百度百科。堆的實質是一棵完全二叉樹,即任何非葉子節點的關鍵字都不大於或者不小於其左右孩子節點的關鍵字。根據情況則分爲大根堆和小根堆。由上述性質可知大頂堆的堆頂的關鍵字肯定是所有關鍵字中最大的,小頂堆的堆頂的關鍵字是所有關鍵字中最小的。


二、堆排序的思想

  通過從父節點向子節點不斷的下探進行比較,將較大/較小的數保留在父節點,最終第一趟排序結束後數組中最小或最大的數必定在堆頂,將堆頂與最後一位數進行交換,令數組長度減少1,即不考慮這個已經排序完成的數字,對剩餘的數據再次進行第二趟排序,直至全體有序爲止。



三、代碼實現

#include 
//降序
void HeapAdjust (int *arr,int i,int len)
{
	int tmp;
	int j = 2 * i;
	for (j; j <= len; j *= 2)
	{
		if (j < len && arr[j - 1] > arr[j])
		{
			tmp = arr[j - 1];
			arr[j - 1] = arr[j];
			arr[j] = tmp;
		}
		if (arr[j - 1] > arr[i - 1])
		{
			break;
		}
		else
		{
			tmp = arr[i - 1];
			arr[i - 1] = arr[j -1];
			arr[j - 1] = tmp;
		}
	}

}

void HeapSort (int *arr,int len) 
{
	int tmp;

	for (int i = len / 2; i > 0; i--)
	{
		HeapAdjust(arr,i,len);
	}
	for (int j = len; j > 0; j--)
	{
		tmp = arr[0];
		arr[0] = arr[j - 1];
		arr[j - 1] = tmp;
		HeapAdjust(arr,1,j-1);
	}
}

int main ()
{
	int arr[] = {5,5,8,6,7,11,3};
	int len = (sizeof(arr)/sizeof(arr[0]))-1;    //有效長度
	HeapSort(arr,len);

	return 0;
}


未編寫打印函數,僅通過調試查看了數組的值,成功完成了降序排序。


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