排序演算法總結之堆排序
堆排序算是選擇排序,即按照最小堆的方式,一個一個彈出來,不過這樣子需要額外的陣列來存放彈出來的資料。浙江大學陳越老師的方法,不需要額外的陣列,如下
利用陣列的方式建立一個最大堆
它的工作方式是:每次把最大堆的根節點和下標最大的結點(不一定是數值最小)交換,這樣下標最大的結點即為最大值,如圖所示,a和b交換,a在根節點而b交換到了堆偉。然後把堆的規模減1,如圖即把下邊為3的結點斷了與這個堆的聯絡。這樣最大值就已經放在了排序陣列中它應該在的位置。下一次交換之前先進行下濾,即讓堆重新變為最大堆再次進行交換,一次類推。具體實現程式碼如下
void Swap( ElementType *a, ElementType *b )
{
ElementType t = *a; *a = *b; *b = t;
}
void PercDown( ElementType A[], int p, int N )
{ /* 改編程式碼4.24的PercDown( MaxHeap H, int p ) */
/* 將N個元素的陣列中以A[p]為根的子堆調整為最大堆 */
int Parent, Child;
ElementType X;
X = A[p]; /* 取出根結點存放的值 */
for( Parent=p; (Parent*2+1)<N; Parent=Child ) {
Child = Parent * 2 + 1;
if( (Child!=N-1) && (A[Child]<A[Child+1]) )
Child++; /* Child指向左右子結點的較大者 */
if( X >= A[Child] ) break; /* 找到了合適位置也可能一次也不需要交換 */
else /* 下濾X */
A[Parent] = A[Child];
}
A[Parent] = X;
}
void HeapSort( ElementType A[], int N )
{ /* 堆排序 */
int i;
for ( i=N/2-1; i>=0; i-- )/* 建立最大堆 */
PercDown( A, i, N );
for ( i=N-1; i>0; i-- ) {//i=N-1因為是從小標0開始的
/* 刪除最大堆頂 */
Swap( &A[0], &A[i] ); /* 見程式碼7.1 */
PercDown( A, 0, i );//這裡知道0結點不是最大值即對0結點下濾
}
}
相關文章
- 演算法與資料結構之原地堆排序演算法資料結構排序
- 排序演算法__堆排序排序演算法
- 排序演算法-堆排序排序演算法
- 排序演算法 - 堆排序排序演算法
- 夯實基礎:排序演算法之堆排序排序演算法
- 排序演算法總結之希爾排序排序演算法
- 堆排序演算法排序演算法
- #排序演算法#【3】堆排序排序演算法
- 演算法學習之選擇排序和堆排序:演算法排序
- 排序演算法總結之歸併排序排序演算法
- 資料結構與演算法——堆排序資料結構演算法排序
- 【資料結構與演算法】堆排序資料結構演算法排序
- 資料結構與演算法:堆排序資料結構演算法排序
- 複習資料結構:排序演算法(六)——堆排序資料結構排序演算法
- 排序演算法總結之直接選擇排序排序演算法
- 插入、冒泡、歸併、堆排序、快排總結排序
- 資料結構&演算法實踐—堆排序資料結構演算法排序
- 圖解堆排序演算法圖解排序演算法
- C#堆排序演算法C#排序演算法
- 演算法導論-堆排序演算法排序
- 『演算法』之 初級排序演算法總結演算法排序
- 【資料結構】堆排序資料結構排序
- Python 一網打盡<排序演算法>之堆排序演算法中的樹Python排序演算法
- 【譯】Swift演算法俱樂部-堆排序Swift演算法排序
- 排序演算法總結排序演算法
- #排序演算法#【6】排序演算法總結排序演算法
- 看懂堆排序——堆與堆排序(三)排序
- 堆排序排序
- 資料結構之堆 → 不要侷限於堆排序資料結構排序
- 學習筆記--- 比較排序之堆排序筆記排序
- (建議收藏)2020最新排序演算法總結:冒泡、選擇、插入、希爾、快速、歸併、堆排序、基數排序排序演算法
- 排序演算法全總結排序演算法
- 前端 排序演算法總結前端排序演算法
- 常用排序演算法總結排序演算法
- 資料結構 堆排序 c Swift資料結構排序Swift
- js堆排序JS排序
- [JAVA]堆排序Java排序
- 《排序演算法》——堆排序(大頂堆,小頂堆,Java)排序演算法Java