一:演算法介紹
堆是一種資料結構,可以看作是一可完全二叉樹,這棵完全二叉樹滿足:所有的雙親節點都不大於(不小於)其左右孩子節點的值,叫做小頂堆(大頂堆);
(考慮遞增排序)
假定我們要構造大頂堆,這棵完全二叉樹的根節點就是當前序列中的最大值,根據這一思想我們就可以把當前序列執行堆排序,找到最大值,與當前序列的最後乙個元素交換,再把除最後乙個元素以外的序列執行堆排序,直到當前序列需要排序的就乙個元素結束。
二:一次執行流程
原始序列
491:建堆
2:調整
從第乙個非葉子節點開始(從右向左,從下向上)
① 調整 97 : 97 > 49
滿足條件不需要。
② 調整 65 :65 > 13 65 >27 滿足條件不需要。
③ 調整 38: 38 < 97 38 < 76,需要調整 (注:在這裡值得一提的是有個小技巧,程式設計時如果按這樣比較比較麻煩,所以在程式設計時我們這樣考慮,如果該非葉子結點同時有左右孩子,則先比較左右孩子的值選最大值與該節點交換)。
交換後38是
49的根節點又不滿足定義,則在調整得到
④ 調整 49 :
49<97 49 < 65
則最終調整為:
相信到這裡小夥伴都看懂了將序列調整為堆的過程,下面就讓我們**實現一下。
三:**實現
我們用到了一顆完全二叉樹來進行對序列實現堆,對於完全二叉樹的儲存方式我們選用順序儲存結構,採用陣列的方式。當我們用陣列來表示完全二叉樹時,陣列的中i位置元素的左孩子在
2*i處
(2*j
小於元素個數
) 右孩子在
2*i+1
處。所以這裡的陣列下標從
1開始,下標
0可以選擇不用,還有根據完全二叉樹的性質和該儲存方式的特點我們很容易發現第乙個非葉子結點在
n/2處(
n是元素的個數
,0處的元素不算)。如下:
(8)n=length-1;
49
1public
class
duisort ;67
for(int n = num.length-1; n>=1; n--)
13//
一次堆排序後將根節點與元素最後乙個元素交換
14int temp =num[n];
15 num[n] = num[1];
16 num[1] =temp;
1718}19
for(int i = 1 ; i<=num.length-1;i++)
2223}24
//將序列進行堆
25private
static
void shift(int num, int low, int
heigh)
30if(num[j] >temp)
35else38}
39 num[i] =temp;40}
41 }
資料結構 堆排序 堆排序 Heap Sort
堆排序是一種選擇排序,其時間複雜度為o nlogn 堆的定義 n個元素的序列當且僅當滿足下列關係之一時,稱之為堆。情形1 ki k2i 且ki k2i 1 最小化堆或小頂堆 情形2 ki k2i 且ki k2i 1 最大化堆或大頂堆 其中i 1,2,n 2向下取整 若將和此序列對應的一維陣列 即以一...
資料結構 堆排序
include include void maxheapify int a,int length,int i void buildmaxheapify int a,int length void heapsort int a,int length void main void printf heap...
資料結構 堆排序
1 堆排序的時間複雜度與歸併排序相同,o nlogn 堆排序的優勢在與他只需要固定數量的額外空間,堆排序要比空間複雜性為o n 的歸併排序稍微慢一些,但是比空間複雜性為o 1 的歸併排序要快。2 對序列 26,5,77,1,61,11,59,15,48,19 進行堆排序 過程 調整最大堆 二叉堆 v...