最近看完一個電視劇,豬腳是胃無限和難忘雞。比較奇怪的是整個電視劇沒有講愛得死去活來的男女之情反而講的是男男之間純純的基情,不過別說還挺好看。有種感受就像:天下人負你又如何,我定然站你這邊...讓我想到了當今社會的一些人,這類人習慣權衡利弊後「站隊」,或察言觀色後隨波逐流不顧真理事實。這部劇表達的三觀就像一股清流,人生可貴一知己,讓我心裏很有觸動。很喜歡胃無限說的一句話:管他熙熙攘攘陽關道,我非要一條獨木橋走到黑。人生可貴一知己,能在你們都詆譭不信任甚至敵視你的時候還義無反顧的支持你,那也真是三生有幸了吧。希望看到本篇的朋友們都能找到人生中的知己,即便沒有這我的,也能堅持一些比較正確的原則。比較感同身受的是,那些見不得人的歪門邪道終究是上不了檯面的...java
以最大堆爲例,利用最大堆結構的特色:每一個最大堆的根節點必然是數組中最大的元素,構建一次最大堆便可獲取數組中最大的元素。剔除最大元素後,反覆構建餘下數字爲最大堆獲取根元素最終保證數組有序。算法
以上都是廢話,建議直接看圖數組
知足父節點大於或等於左右子節點即爲最大堆,最大堆二叉樹以及對應數組如上圖。bash
以數組int n[] = { 6, 5, 2, 7, 3, 9, 8 }爲例:ui
1、構建最大堆:編碼
從最後一個非葉子節點(計算公式爲n.length/2-1,可自行驗證)開始,從後往前進行調整構建,調整的規則是:若子節點大於父節點,則將子節點中較大的節點元素與父節點交換。spa
1.調整節點2(數組索引2),對比子節點9和8,將9和8進行交換; 3d
2.調整節點5(數組索引1),對比子節點7和3,將7和5進行交換; 指針
3.調整節點6(素組索引0),對比子節點7和9,將6和9進行交換; code
2、取出最大堆數組的第一位根元素與數組末位元素交換:
根據上述構建最大堆的原理能夠得出堆排序的完整過程
public class Test {
public static void main(String[] args) {
int n[] = { 6, 5, 2, 7, 3, 9, 8 };
heapsort(n);
System.out.print("堆排序結果:");
for (int m : n) {
System.out.print(m + " ");
}
}
/** * 堆排序 * @param n 待排序數組 */
public static void heapsort(int n[]) {
for (int i = n.length - 1; i >= 1; i--) {
buildHeap(n, i);
swap(n, 0, i);
}
}
/** * * @param n 待排序數組 * @param end 待排序數組末位下標 */
public static void buildHeap(int n[], int end) {
int len = end + 1;
for (int i = len / 2 - 1; i >= 0; i--) {
//堆中i節點對應的左右子節點l和r
int l = 2 * i + 1, r = l + 1;
//指向較大數節點的指針
int p = l;
if (r <= len - 1 && n[l] < n[r]) {
p = r;
}
if (n[i] < n[p]) {
swap(n, i, p);
}
}
}
/** * * @param n 待排序數組 * @param i 待交換數字數組下標 * @param j 待交換數字數組下標 */
private static void swap(int n[], int i, int j) {
n[i] ^= n[j];
n[j] ^= n[i];
n[i] ^= n[j];
}
複製代碼
堆排序結果:2 3 5 6 7 8 9
複製代碼
1、heapsort堆排序方法
for循環(注意循環次數比數組長度小1,緣由最低2個數構成最大堆)
i.根據數組長度構建最大堆;
ii.交換數組首位(最大堆根節點)與數組末位;
2、buildHeap構建最大堆
1.聲明數組長度len;
2.for循環從最後一個非葉子結點開始往回遍歷到根節點;
i.找到當前非葉子結點的左右子節點下標;
ii.聲明較大數指針,默認指向左子節點;
iii.對比左右子節點,若右子節點存在且右大於左則指向右子節點;
iv.對比交換較大的子節點和父節點。
複製代碼
本篇以最簡單的圖文形式講解八大排序之一的堆排序的核心思想和具體實現,堆排序和快速排序均爲相對其餘排序出現頻率最高的排序算法。最後,若是以爲本篇對你有所啓發或幫助,不妨關注走一波0.0