排序演算法 堆排序

2021-07-11 21:30:18 字數 1502 閱讀 1521

堆排序(heap sort)

就是利用堆進行排序的演算法,它的基本思想是:

將待排序的序列構造成乙個大頂堆(或小頂堆)。

此時,整個序列的最大值就是堆頂的根結點。將它移走(就是將其與堆陣列的末尾元素交換,此時末尾元素就是最大值)

,然後將剩餘的n-1個序列重新構造成乙個堆,這樣就會得到n個元素中的

最大值。

如此反覆執行,便能得到乙個有序序列了。

堆排序的過程大致分為4大步:

1.

利用原來的陣列建立乙個最大堆。此時,陣列中最大的元素肯定是在data[0]中儲存的。

2.

把最大堆的data[0]與data[n-1]元素交換,此時最大的元素就跑到data[n-1]中了。3.忽略最後乙個元素,調整整個堆,

使得元素交換以後又是乙個最大堆。

4.將最大堆的data[0]與data[n-2]進行交換,以此類推。

整個程式的難點在於:如何調整乙個堆,讓他變為最大堆。這個問題可以遞迴的解決:假設某個節點的左右子樹已經是最大堆了,那麼如需要將根節點與左右子樹相比較,然後(如果需要的話)與左右子樹中最大的交換;但是交換完以後,可能會引起左右子樹中的一顆不再是最大

堆,那麼就對於以左(或者右)子樹為根的子樹繼續重複前面的過程,

直到遇見葉子節點

(因為對每個子樹進行調整的時候,需要先和根結點比較並交換,然後再向下進行調整交換,所以遞迴的終結條件就是遇到葉子節點)

堆排序是對選擇排序進行改進的排序演算法,堆排序演算法的時間複雜度是o(nlogn)。

//堆排序

//調整堆,使以index為根的子樹成為最大堆

void headadjust(parraylist list,int index,int length) }

/*利用陣列初始化乙個最大堆,就需要從最後乙個葉子節點的父節點開始,

依次呼叫上面的heapadjust函式就行了:

*///自底而上的呼叫headadjust將陣列變成乙個最大堆

void buildmaxheap(parraylist list) }

/*將最大堆的根與陣列的最後乙個元素交換,然後忽略最後乙個元素,

重新調整堆。然後取倒數第二個元素重複上述步驟:

*///堆排序

void heapsort(parraylist list)

printf("最終結果:");

printarraylist(list);

}

排序演算法 堆排序

1 什麼是堆 首先它是一顆完全二叉樹,並且父結點的值大於子節點的值 最大堆 或父結點的值小於子結點的值 最小堆 小根堆 根結點 亦稱為堆頂 的關鍵字是堆裡所有結點關鍵字中最小者的堆稱為小根堆,又稱最小堆。大根堆 根結點 亦稱為堆頂 的關鍵字是堆裡所有結點關鍵字中最大者,稱為大根堆,又稱最大堆。2 堆...

排序演算法 堆排序

花了一晚上時間研究堆排序,這個排序困擾了哥很久,終於搞清楚了。一 堆的定義 1.父結點的鍵值總是大於或等於 小於或等於 任何乙個子節點的鍵值 2 每個結點的左子樹和右子樹都是乙個二叉堆 都是最大堆或最小堆 二 已知結點 i 則它的子結點 為2 i 1 與 2 i 2 父節點為 i 1 2 三 堆排序...

排序演算法 堆排序

由於不經常使用,之前學習看過的演算法都給忘了。現在把他們寫下來,記錄下來,以方便以後查閱。本篇文章的 即為堆排序的 主函式中是對輸入檔案中的序列進行排序,並將結果輸出到乙個檔案中。這是一種形式類似於google codejam的測試方法。include include using namespace...