演算法系列15天速成 第二天 七大經典排序 中

2021-08-26 21:06:20 字數 2147 閱讀 7977

首先感謝朋友們對第一篇文章的鼎力支援,感動中.......

今天說的是選擇排序,包括「直接選擇排序」和「堆排序」。

話說上次「氣泡排序」被快排虐了,而且「快排」贏得了內庫的重用,眾兄弟自然眼紅,非要找快排一比高下。

這不今天就來了兩兄弟找快排算賬。

1.直接選擇排序:

先上圖:

說實話,直接選擇排序最類似於人的本能思想,比如把大小不一的玩具讓三歲小毛孩對大小排個序,

那小孩首先會在這麼多玩具中找到最小的放在第一位,然後找到次小的放在第二位,以此類推。。。。。。

對的,小孩子給我們上了一課,

第一步: 我們拿80作為參照物(base),在80後面找到乙個最小數20,然後將80跟20交換。

第二步: 第一位數已經是最小數字了,然後我們推進一步在30後面找一位最小數,發現自己最小,不用交換。

第三步:........

最後我們排序完畢。大功告成。

既然是來挑戰的,那就5局3勝制。

比賽結果公布:

堆排序:

要知道堆排序,首先要了解一下二叉樹的模型。

下圖就是一顆二叉樹,具體的情況我後續會分享的。

那麼堆排序中有兩種情況(看上圖理解):

大根堆: 就是說父節點要比左右孩子都要大。

小根堆: 就是說父節點要比左右孩子都要小。

那麼要實現堆排序,必須要做兩件事情:

第一:構建大根堆。

首先上圖:

首先這是乙個無序的堆,那麼我們怎樣才能構建大根堆呢?

第一步: 首先我們發現,這個堆中有2個父節點(2,,3);

第二步: 比較2這個父節點的兩個孩子(4,5),發現5大。

第三步: 然後將較大的右孩子(5)跟父節點(2)進行交換,至此3的左孩子堆構建完畢,

如圖:

第四步: 比較第二個父節點(3)下面的左右孩子(5,1),發現左孩子5大。

第五步: 然後父節點(3)與左孩子(5)進行交換,注意,交換後,堆可能會遭到破壞,

必須按照以上的步驟一,步驟二,步驟三進行重新構造堆。

最後構造的堆如下:

第二:輸出大根堆。

至此,我們把大根堆構造出來了,那怎麼輸出呢?我們做大根堆的目的就是要找出最大值,

那麼我們將堆頂(5)與堆尾(2)進行交換,然後將(5)剔除根堆,由於堆頂現在是(2),

所以破壞了根堆,必須重新構造,構造完之後又會出現最大值,再次交換和剔除,最後也就是俺們

要的效果了,

發現自己兄弟被別人狂毆,

同樣,快排也不甘示弱,誰怕誰?

結果公布:

堆排序此時心裡很尷尬,雙雙被ko,心裡想,一定要撈回面子,一定要贏,

於是堆排序提出了求「前k大問題」。(就是在海量資料中找出前幾大的資料),

快排一口答應,小意思,沒問題。

雙方商定,在2w隨機數中找出前10大的數:

求前k大的輸出結果:

最後堆排序趕緊拉著直接選擇排序一路小跑了,因為求前k大問題已經不是他原本來的目的。

ps: 直接選擇排序的時間複雜度為:o(n^2)

堆排序的時間複雜度:o(nlogn)

演算法系列15天速成 第三天 七大經典排序 下

今天跟大家聊聊最後三種排序 直接插入排序,希爾排序和歸併排序。直接插入排序 這種排序其實蠻好理解的,很現實的例子就是俺們鬥地主,當我們抓到一手亂牌時,我們就要按照大小梳理撲克,30秒後,撲克梳理完畢,4條3,5條s,哇塞.回憶一下,俺們當時是怎麼梳理的。最左一張牌是3,第二張牌是5,第三張牌又是3,...

演算法系列15天速成 第三天 七大經典排序 下

今天跟大家聊聊最後三種排序 直接插入排序,希爾排序和歸併排序。直接插入排序 這種排序其實蠻好理解的,很現實的例子就是俺們鬥地主,當我們抓到一手亂牌時,我們就要按照大小梳理撲克,30秒後,撲克梳理完畢,4條3,5條s,哇塞.回憶一下,俺們當時是怎麼梳理的。最左一張牌是3,第二張牌是5,第三張牌又是3,...

演算法系列15天速成 第一天 七大經典排序 上

演算法就好比程式開發中的利劍,所到之處,刀起頭落。針對現實中的排序問題,演算法有七把利劍可以助你馬道成功。using system using system.collections.generic using system.linq using system.text using system.di...