常見排序算法:堆排序算法

基本思想:先將待排序數據化爲完全二叉樹,從length/2+1處開始尋找他的左/右子節點,將較大值與父節點進行交換,最後遍歷到根節點處,此時根節點爲所有數中的最大值,將該值與最後一個元素進行交換,length=length-1,又從父節點開始進行比較,繼續尋找較大值。將找到的較大值與length-2處進行交換。依次類推。

 1.首先將待排序的數組元素轉換爲完全二叉樹,根節點對於數組第一個元素,按先序遍歷進行排序,即根節點,左子節點,右子節點。

2.待排序數組長度爲length=8,首先進行堆的初始化,定義一個for循環for(i=length/2-1;i>0;i--)。i首先等於8/2-1=3;因此從a[3]處作爲父節點,尋找比它大的左右子節點。此時6作爲父節點,3作爲左子節點,6沒有右子節點,6是最大值因此不需要進行交換。進入下一輪for循環

3.i此時等於2。因此a[2]處作爲父節點,它的左子節點右子節點分別爲6和1,6比4大,此時最大值位置max=2*2+1處,1比4小,max位置仍爲2*2+1處,因此交換a[2]與a[2*2+1]處的元素。交換完成後a[5]作爲父節點繼續尋找它的左右子節點,此時a[5]已經爲葉子節點,沒有子節點,因此該輪循環結束。

4.i此時等於1。因此a[1]處作爲父節點,它的左子節點右子節點分別爲6和7,5<6,max位置爲3處。5<7,max位置變爲4。因此交換a[1]與a[max]處的元素。交換後5變爲右子節點,此時5已經是葉子節點因此不需要進行繼續尋找子節點,該輪循環結束。

5.i此時等於0。因此a[0]處作爲父節點,它的左子節點右子節點分別爲7和6,7<12,6<12,max位置爲0。此輪循環結束,i變爲-1循環結束。此時父節點爲數組中的最大值。

6.進入另外一個循環for(i = len - 1; i >=0; i--),該循環將棧頂元素與最後一個元素進行交換。i=7,將a[0]與a[7]進行交換。

7.此時又從棧頂開始,a[0]作爲父節點,比較左右子節點。7>3,max=1。交換a[1]和a[0]。

7.交換的元素a[1]不是葉子節點,需要繼續迭代進行交換。保證交換的元素比它子節點大。因此將a[1]與a[3]進行交換。12作爲最大元素不在參與上面的交換。此時7作爲最大值位於父節點處。

8.將該循環將棧頂元素與最後一個元素進行交換。此時最後一個元素爲a[length-2]。即7與1進行交換。

9.交換後i=length-1;又從a[0]開始繼續迭代比較。將1和左子節點的6進行交換。交換後繼續將1作爲父節點和它的右子節點5進行交換。

10.當i<0時,排序完成。

代碼:


//list:待調整的數組 index:待調整的節點下標 len:數組長度
void HeapAdjust(int list[], int index, int len)
{
	int max = index;//保存父節點下標
	int lchild = index * 2 + 1;//下標從0開始
	int rchild = index * 2 + 2;//下標從0開始

	//左子節點大於父節點
	if (lchild<len&&list[lchild]>list[max])
	{
		max = lchild;
	}
	//右子節點大於父節點
	if (rchild<len&&list[rchild]>list[max])
	{
		max = rchild;
	}
	if (max!=index)
	{
		swap(list[max], list[index]);
		HeapAdjust(list, max, len);
	}

}
//初始化堆,大頂堆,從小到大
void HeapSort(int list[], int len)
{
	//初始化堆
	for (int i = len / 2 - 1; i >= 0; i--)
	{
		HeapAdjust(list, i, len);
	}
	//交換堆頂元素和最後一個元素
	for (int i = len - 1; i >=0; i--)
	{
		swap(list[0],list[i]);
		HeapAdjust(list, 0, i);
	}
}
int main()
{
	int list[] = { 12, 5, 4, 6, 7, 6, 1 ,3};

	HeapSort(list, sizeof(list) / sizeof(int));

	for (int i = 0; i < sizeof(list) / sizeof(int); i++)
	{
		cout << list[i] << endl;
	}
}

堆排序是一種不穩定的排序方法,最好、最壞、平均時間複雜度:O(n\log n),空間複雜度爲O(1)

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