堆排序、堆排序優化、索引堆排序
注: 堆排序、索引堆排序 都是不穩定的排序。
注:索引最大堆排序有誤!!!有沒有大神可以指點一二???
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...