照舊,老鐵先開始講理論:
理論:堆排序,就是根據大頂堆的特性——父節點總是大於子節點,則root節點就是堆中的最大數值,所以只要每次取出root節點,就可以完成排序。
so,依然是迴圈排序,
迴圈內分兩步走:
第一步:將陣列按大頂堆結構排列
第二步:取出堆頂資料
。。。第一步:將剩餘陣列按大頂堆結構排列
第二部:取出對頂資料
。。。————————————————————————————————
所以思路就明確了,這是個巢狀迴圈,或者遞迴。
跳出條件,是所有數都已經取過。
————————————————————————————————
那思路是有了,**怎麼寫呢?
咱們碼農要明確,程式離不開兩個東西:1,資料結構。2,計算邏輯。
萬變不離其宗,如果離了……那當我沒說……
1,資料結構
大家都知道,這是傳統手藝。堆結構,用陣列來儲存 array。
root節點位於 array[0] 位置。
root的左子節點位於 array[1] 位置
root的右子節點位於 array[2] 位置
如果用 index 表示元素下標。
則滿足父節點位於 array[i]
左子節點位於 array[2i+1]
右子節點位於 array[2i+2]
好了,資料模型已經描述清晰。
那咱們初始化乙個陣列:
sort_init :=
int
開始講計算的邏輯
2,計算邏輯
其實主要是拆解第一步的堆排列。將複雜問題拆解成最小單元,這樣就比較容易解決了。
那對於堆這種結構來說,最小單元是這個樣子:
那最小單元的計算邏輯,就是比較這三個數,然後將每個數放在合適的位置。
偽**是這樣的:
arr=
introot=a的下標
child=b的下標
if c 並且 c>b
比較root指向的元素,child指向的元素
大的位於堆頂arr[
0]位置
好,那咱們寫成乙個方法:
fun sor_stack
(arr [
]int
,start int
,end int
)if child+
1<=end&&arr[child+1]
>arr[child]
if arr[child]
>arr[root]
}}
這是3個節點的情況。
那如果有多個節點,咱們就要開始遞迴**了。
遞迴,主要是找到入點,和出點。能進去能出來,就成功了。
func
sort_stack
(arr [
]int
,start int
,end int)[
]int
if child+
1<=end&&arr[child+1]
>arr[child]
if arr[child]
>arr[root]
else
return arr
}
對於堆的處理函式已經有了,
那接下來就是按步驟執行排序。
1,獲得乙個陣列,上面已經有了,就用 sort_init
2,將陣列初始化為堆結構,這時候可以用到咱們的sort_stack函式,從後往前處理,
先處理再處理
最後處理
將這個過程封裝成函式
// 找到c所在的位置
func
init_fun
(sort_init [
]int)[
]int
return sort_init
}
3,利用堆結構排序
不斷的取出堆頂元素
重新組織堆結構
res :=
intfor
tmp :=
int// 將堆頂元素放到res的0位置
res =
(tmp,res...
)// 去除堆頂元素
sort_init = sort_init[1:
]// 重新組織堆結構
sort_init =
init_fun
(sort_init)
}
排序完成!
然後,我們來看看,這個過程,有沒有辦法優化呢?
既然我說了,那肯定是可以優化的。因為我們用了兩個陣列——
sort_init(初始化的陣列)
res(儲存排序結果的陣列)
現在我們重寫一下最後的排序過程,將兩個陣列合併為同乙個。其實只要將堆頂元素放在陣列尾部,
然後縮短堆結構覆蓋的範圍即可。
**如下:
for end :=
len(sort_init)-1
; end >
0; end--
go 排序演算法 堆排序
1.5 堆排序 堆排序 heapsort 是指利用堆這種資料結構所設計的一種排序演算法。堆積是乙個近似完全二叉樹的結構,並同時滿足堆積的性質 即子結點的鍵值或索引總是小於 或者大於 它的父節點。核心思路 1 depth length 2 1 節點深度,n,2n 1,2n 2 2 遞迴思想,找出最大值...
堆排序演算法實現
include define true 1 define false 0 typedef struct recordtype void sift recordtype r,int k,int m 調整堆 r i t void crt heap recordtype r,int length 建立堆 ...
Go語言 堆排序
1 前言 在了解堆排序之前,需要知道堆的一些特徵,那就是堆就是乙個完全二叉樹,所以需要了解完全二叉樹的特點 完全二叉樹的特點 1 葉子節點只能在最大的兩層出現 2 如果i 1,結點就是根結點,如果i 1,則其雙親parent i i 2 3 如果2i n,則結點無左孩子,如果2i 1 n,則結點無右...