堆排序 堆排序優化 索引堆排序

2021-09-26 21:31:41 字數 2481 閱讀 6982

堆排序、堆排序優化、索引堆排序

注: 堆排序、索引堆排序 都是不穩定的排序。

注:索引最大堆排序有誤!!!有沒有大神可以指點一二???

1、堆:

所有元素 都從索引0開始

父親結點索引:i;

左孩子結點索引: 2i+1;

右孩子結點索引: 2i+2;

左後乙個非葉子結點索引:(n-1)/2; 用於構建堆,從最後乙個非葉子結點索引開始調整堆,直至到達索引為0的首個父親結點

2、堆排序(公升序為例):

共兩步:

step1、構建堆

step2、原地堆排序

step1、構建堆

從最後乙個非葉子結點索引開始調整堆,直至到達索引為0的首個父親結點。

step2、原地堆排序:

每次迴圈,使用o(1)的時間索引到當前迴圈的最大值a[0],

將該最大值交換到陣列末尾,

陣列元素減1,

對新的堆進行調整,為下一輪迴圈做準備。

3、調整堆函式shiftdown()思路:

從當前父親結點k開始,

每次比較 當前父親結點值與該父親結點對應的左右孩子節點中的最大值,

如果 「父親結點值」>「最大孩子節點值」,就代表堆調整好了,提前結束迴圈。

如果 「父親結點值」<「最大孩子節點值」,那麼,當前"父親結點值"更換為「最大孩子節點值"。更新父親結點值,繼續向下調整。

4、區別

4.1、普通堆排序的 shiftdown中使用「移動賦值」操作 與 「交換資料元素」 操作 區別:

使用「移動賦值」操作 比 使用"交換資料元素" 操作,的時間損耗少了2/3.

eg:shiftdown中總共進行m次迴圈,

—使用「移動賦值」操作:所有運算元為:m次移動+1次賦值+1個額外空間的申請,共計 m+1次 賦值操作 + 1個額外空間的申請

—使用「交換資料」操作:所有運算元為:3m次賦值+1個額外空間的申請, 共計 3m 次賦值操作 + 1個額外空間的申請

4.2、索引堆排序 與 普通堆排序 區別:

(1)定義

索引堆:資料域 與 索引域 是分開儲存的。

排序過程中:資料元素的相對位置保持不變,這樣可以使得 堆排序 優化為穩定的排序;改變的是索引陣列的相對位置。

最後形成的索引陣列,就是所謂的索引堆。

索引堆排序:

不改變原來資料域元素的位置,只是新開闢了乙個索引域來代表原來資料域的相應資料進行排序,其本質還是乙個堆排序。重點內容

(2)排序

比較值大小時,用的是 資料域 data陣列中的元素

移動、賦值、交換時,用的是 索引域 index陣列中的元素

(3)排序輸出

索引堆排序:輸出時,只需依次取出索引陣列中對應索引的對應資料域元素,即可。

普通堆排序:依次輸出,改變後的陣列元素。

(4)消耗

索引堆排序 比 普通堆排序 多占用乙個o(n)的int型空間,用於存放代替資料元素進行堆排序的索引資料。

(5)優點

索引堆排序與普通堆排序,優點為:

如果原來資料域中,每乙個元素的資料結構很複雜,或者資料的size都很大,那麼,使用普通堆排序,在移動、賦值、交換資料域的元素過程花費會非常的巨大。

而使用索引堆排序,則只是花費了乙個o(n)的int型別空間,在在移動、賦值、交換操作中,都是乙個int型的索引元素在參與運算,花費非常小。

5、核心**:

///三個版本的原地堆排序

//version1 最大堆排序 shiftdown()中"交換資料元素"操作

void shiftdown(int a, int n, int k)

}void maxheapsort(int a, int n)

}//version2 最大堆排序優化 shiftdown()中使用「移動賦值」操作取代"交換資料元素" 操作

//思路源於 插入排序

void shiftdown2(int a, int n, int k)

a[k] = tmp;//賦值

}//有問題 !!!version3 最大索引堆排序  shiftdown()中使用「移動賦值」操作

void shiftdown3(int a, int index, int n, int k)

index[k] = tmp_index;//賦值的是 索引域中元素

}void indexmaxheapsort(int a, int index, int n)

}void printindexmaxheap(int a, int index, int n)

//version3 end

6、完整**,請移步我的github

7、測試:

起始資料: 2 9 5 6 4 10 8 3 5 8

//建成堆如下:

10/     \

9       8

/   \    /  \

6     8  5    2

/ \   /

3   5 4  

測試結果如下圖所示:

堆排序 堆排序優化 索引堆排序

堆排序 堆排序優化 索引堆排序 注 堆排序 索引堆排序 都是不穩定的排序。注 索引最大堆排序有誤!有沒有大神可以指點一二?1 堆 所有元素 都從索引0開始 父親結點索引 i 左孩子結點索引 2i 1 右孩子結點索引 2i 2 左後乙個非葉子結點索引 n 1 2 用於構建堆,從最後乙個非葉子結點索引開...

堆排序 模擬堆排序

838.堆排序 輸入乙個長度為n的整數數列,從小到大輸出前m小的數。輸入格式 第一行包含整數n和m。第二行包含n個整數,表示整數數列。輸出格式 共一行,包含m個整數,表示整數數列中前m小的數。資料範圍 1 m n 1051 m n 105,1 數列中元素 1091 數列中元素 109 輸入樣例 5 ...

堆排序 模板 堆排序

biu 堆排序是乙個不穩定的排序演算法,對資料不敏感,時間複雜度穩定,主要分為兩部分 建堆 堆排序。其中建堆的時間複雜度是 o n o n o n 的,而排序選出乙個最大 最小值的過程是 o l ogn o logn o logn 的,一共需要n次操作,故總共的時間複雜度是 o n logn o n...