5分鐘回憶快速排序

任務描述

在這裏插入圖片描述

給我從小到大排序!!!

算法思路

 首先“瞎選”一個值,找到其最終位置,即排好序後它在哪,並把小於它的丟左邊,大於的丟右邊。對左右子部分重複操作,直至子部分都只剩一個元素,則所有元素都找到了其該在的位置。
在這裏插入圖片描述
在這裏插入圖片描述

如何瞎選

第一個?
如果數組正好是從大到小的,那我每一輪都要擼(比較)nn個數才能找到選的數應該在哪,擼nn輪,實現過程相當與變成了選擇排序(先把一個數丟最後面,再第二個…),複雜度O(n2)O(n^2)
生成隨機數?
有意思嘛,本來就要減少運行時間,還要用代碼去生成隨機數,浪費時間。
簡單做法
取中間的數,無所謂了,反正要隨機,去算一組數的中值更麻煩。

怎麼丟來丟去

過程中得把小的丟左邊,大的丟右邊,怎麼實現呢,難道另申請一個數組小的從前往後存,大的從後往前存?浪費空間!肯定動的是原數組,以下通過選6作爲第一輪基準值來說明

坑位法

既然要對原數組變動,則需要留一個坑位來避免數據丟失,不然變動了值後面要用怎麼辦,誰做第一個坑呢,當然是基準值的位置!先備份6,然後從頭開始遍歷數組,一旦發現有比選中數6大的,比如第3個數7,把它丟到6的位置,這時候第3個數7已經沒用了,不怕被覆蓋,成爲了新的坑位;然後從尾開始遍歷數組,一旦發現有比選中數7小的,比如3,把3丟到新的坑位即將第三個數複製爲3;然後從4四個數開始往後遍歷…直到遍歷完整個數組,完成第一輪!下圖紅色圈代表坑位
在這裏插入圖片描述

交換法

一樣的思路,從頭開始遍歷,一旦發現有大的數停一下,然後從後遍歷,一旦發現有小的數,立刻交換這兩個數,免去了坑位…
ps:得注意角標問題,可以各後退一步

複雜度分析

最好情況

每次找的正好是中值,則除了加上這次耗費n次比較才找到自己的位置,還加上子部分的複雜度。最後結果爲O(nlogn)O(nlogn)
T(n)={1,n=12T(n2)+n,n>1 T(n) = \begin{cases} 1, & \text{n=1} \\ 2T(\frac{n}{2})+n, & \text{n>1} \end{cases}
T(n)=2(2T(n22)+n2)+n=22T(n22)+2n=33T(n23)+3n=2log2n+nlog2n=nlog(n) \begin{aligned} T(n) &=2(2T(\frac{n}{2^2})+\frac{n}{2})+n\\&=2^2T(\frac{n}{2^2})+2n\\&=3^3T(\frac{n}{2^3})+3n\\&=2^{\log_2 n}+n\log_2 n\\&=nlog(n) \end{aligned}

最壞情況

瞎選第一個,且數組倒敘的情況,複雜度O(n2)O(n^2)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章