資料結構,學後面的忘記前面的,學完前面的忘記後面的,何解?圖形化它,強記它,能夠按自己的思路復現它一次,不行再來一次,還不行再來一次!!
學習資料結構,對我來說,比較舒服的方式:
提煉出問題,到底 求 什麼?
圖形化描述其實現過程
程式設計實現(找個例子跟著做更好)
判斷條件 怎麼實現
核心問題程式設計
實現一次簡單執行 優化
堆排序
是選擇排序
的一種,目的是利用最大堆
的特點(最大堆就是根結點是最大值),得到我們想要的最大;
然後把這個最大值交換到待排序資料的最後面去,這樣n個待排資料,就有1個是確定順序的了,還剩下n-1個未排資料;
對剩下的n-1個重新堆化,迴圈往復,每次得到最大值都放到後面去,就完成排序了。
完結,撒花!
首先,要明白堆排的目的是啥?
堆排是選擇排序的一種,選擇排序(我說的是上公升法),就是每個選出最大值,然後,交換到最後去。
為什麼利用堆,來進行排序。堆能幹嘛,堆這個樹結構它的根,是所有結點中的最大值,我們利用堆就是為了要它的最大值。
所以,得出結論,堆排就是利用堆來進行選擇排序。
b.1 主流程
令j=n
;
j
是堆的最大下標,即堆的當前尾指標
將a[1]
與a[j]
交換,將最大元換到當前尾
j=j-1;
使堆的範圍縮小
重新堆化(是關鍵步驟)
即調整a[1]~a[j]
,使之成為乙個新堆
若j>1
,則轉步驟2;否則排序結束
b.2 重新堆化
大兒子上公升做父,小根逐步下降
實質就是「子堆合併」
若用i表示當前堆的根的下標,j表示堆的尾的下標。重新堆化的具體步驟如下:
i = 1
若i
是葉,若a[i]
已滿足父大於子的性質,重新堆化結束;否則繼續下一步;
找i的「大兒子」k;
交換a[i]
與a[k]
的值,使根元素下沉。
i=k
,轉步驟2
c.1 主流程
c.1.1 初始堆化
在全部流程開始前,先要進行初始堆化,初始堆化,就是將原資料組,形成乙個堆,其原理利用重新堆化原理:
應該不會有人問為什麼要初始堆化這個問題吧?c.1.2 **
// 主控函式
void heap_sort(int a, int n)
}
c.2 重新堆化
c.2.1 例子
// i是根結點
// j是待調整堆的堆尾的位址
void heapify(int a, int i, int j)
a[i] = x; //原根元素值就位
}
[1] 資料結構 – 中國人民解放軍陸軍工程大學 –陳衛衛、李清等 – 公開課 – 中國大學mooc 資料結構學習筆記 堆排序
堆是一棵完全二叉樹。每個結點的值都大於等於該結點的孩子結點的堆稱為大頂堆,反之則稱為小頂堆。為了使用簡便,我們就用陣列heap來儲存堆結構,heap 1 儲存堆的根結點,如果當前遍歷的結點為heap i 則heap 2i 和heap 2i 1 分別為其左右孩子結點。在了解了堆結構定義之後,我們就可以...
資料結構學習之 排序高階(堆排序)
氣泡排序 一種比較容易理解的排序演算法,可以優化的程度也比較有限 平均 o n 2 最壞 o n 2 最好 o n 最好情況需要在進行迴圈之前加入標誌位,若一次遍歷中,沒有任何兩個資料被交換,則認為序列已經有序,跳出迴圈。此時,時間複雜度為o n 插入排序 選擇乙個資料插入到前面已經排好的有序佇列之...
資料結構學習筆記 堆和堆排序
堆,是一種特殊的樹 經典的應用場景,堆排序,原地的時間複雜度為o nlogn 的排序演算法 堆的兩點定義 每個節點的值都大於等於子樹中每個節點值的堆叫做大頂堆,反之叫做小頂堆 之前說過完全二叉樹適合用陣列儲存,所以堆也用陣列儲存 堆的核心操作有插入元素和刪除堆頂元素,以大頂堆為例 插入元素 todo...