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 插入排序 選擇乙個資料插入到前面已經排好的有序佇列之...