15 資料結構高階十五排序實現之堆排序

2021-08-08 16:20:55 字數 1938 閱讀 3990

15. 資料結構高階十五排序實現之堆排序

「誰要是遊戲人生

, 他就一事無成

; 誰不能主宰自己

, 永遠是乙個奴隸

。--

歌德」

繼續來看下堆排序。

堆排序(heapsort)是指利用堆積樹(堆)這種資料結構所設計的一種排序演算法,它是選擇排序的一種。可以利用陣列的特點快速定位指定索引的元素。堆分為大根堆和小根堆,是完全二叉樹。大根堆的要求是每個節點的值都不大於其父節點的值,即a[parent[i]] >= a[i]。在陣列的非降序排序中,需要使用的就是大根堆,因為根據大根堆的要求可知,最大的值一定在堆頂。

(a)大頂堆序列:(96,83,27,38,11,09)

(b)  小頂堆序列:(12,36,24,85,47,30,53,91)

如圖建堆初始過程:無序序列:(49,38,65,97,76,13,27,49)

從乙個無序序列建堆的過程就是乙個反覆篩選的過程。若將此序列看成是乙個完全二叉樹,則最後乙個非終端節點是第[n/2]個元素,由此篩選只需從第[n/2]個元素開始。

**核心是先將陣列假想為完全二叉樹。那麼偶數字的數是左孩子,奇數字的數是右孩子。

先將陣列進行完全二叉樹處理,然後將根節點提取出來放到陣列最後,將原先陣列的最後乙個元素放到根節點,因為不能保證原先陣列最後乙個的元素是剩下元素中最大的,所以要緊接著做一次處理(此次處理將最後乙個元素除外)。接下去是繼續去根節點放到陣列倒數第二個位置,以此迴圈。

實現如下圖1

#include

"stdio.h"

void

print(

inta

,int

n) 

/** *

已知h[s…m]

除了h[s]

外均滿足堆的定義 *

調整h[s],

使其成為大頂堆

即將對第

s個結點為根的子樹篩選, 

* * @param h

是待調整的堆陣列

* @param s

是待調整的陣列元素的位置

* @param length

是陣列的長度 *

*/void

heapadjust(

inth

,ints,

intlength

)   

if(h[

s]<

h[child]) 

else 

h[s]= tmp;        

// 當前待調整的結點放到比其大的孩子結點位置上

}  //        print(h,length); 

}  

/** *

初始堆進行調整 *

將h[length-1]

建成堆

* 調整完之後第乙個元素是序列的最小的元素 */

void

buildingheap(

inth

,int

length

)   

/** *

堆排序演算法 */

void

heapsort(

inth

,int

length

)   

}  

intmain(); 

printf(

"初始值:

\n"); 

print(h,10); 

heapsort(h,10); 

//selectsort(a,8); 

printf(

"\n堆排序後值:

\n"); 

print(h,10); 

資料結構研究之五 高階排序

1.歸併排序 a.步驟提要 將原有陣列分割平分成兩個陣列,然後分別排序。將排好序的區域性陣列整合成乙個陣列,然後遞迴執行此過程 b.過程 created by 葉子 on 2018 1 27.歸併排序 include iostream using namespace std define max 5...

資料結構(十五)

每組測試第1行包含2個正整數n和 m 1 000 分別是插入元素的個數 以及需要列印的路徑條數。下一行給出區間 10000,10000 內的 n個要被插入乙個初始為空的小頂堆的整數。最後一行給出 m個下標。對輸入中給出的每個下標i,在一行中輸出從h i 到根結點的路徑上的資料。數字間以1個空格分隔,...

資料結構學習之 排序高階(堆排序)

氣泡排序 一種比較容易理解的排序演算法,可以優化的程度也比較有限 平均 o n 2 最壞 o n 2 最好 o n 最好情況需要在進行迴圈之前加入標誌位,若一次遍歷中,沒有任何兩個資料被交換,則認為序列已經有序,跳出迴圈。此時,時間複雜度為o n 插入排序 選擇乙個資料插入到前面已經排好的有序佇列之...