演算法 堆排序(go實現)

2021-10-05 21:39:14 字數 2648 閱讀 3330

照舊,老鐵先開始講理論:

理論:堆排序,就是根據大頂堆的特性——父節點總是大於子節點,則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,則結點無右...