如果要排序乙個陣列,我們先把陣列從中間分成前後兩部分,然後對前後兩部分分別排序,再將排好序的兩部分合併在一起,這樣整個陣列就都有序了。
我們申請乙個臨時陣列 tmp,大小與 a[p…r]相同。我們用兩個游標 i 和 j,分別指向 a[p…q]和 a[q+1…r]的第乙個元素。比較這兩個元素 a[i]和 a[j],如果 a[i]<=a[j],我們就把 a[i]放入到臨時陣列 tmp,並且 i 後移一位,否則將 a[j]放入到陣列 tmp,j 後移一位。
第一,歸併排序是穩定的排序演算法嗎?
\quad
歸併排序是乙個穩定的排序演算法。
第二,歸併排序的時間複雜度是多少?
不管是最好情況、最壞情況,還是平均情況,時間複雜度都是 o(n
logn
)o(nlogn)
o(nlog
n)。第三,歸併排序的空間複雜度是多少?
歸併排序不是原地排序演算法。空間複雜度是 o(n
)o(n)
o(n)
。如果要排序陣列中下標從 p 到 r 之間的一組資料,我們選擇 p 到 r 之間的任意乙個資料作為 pivot(分割槽點)。
我們遍歷 p 到 r 之間的資料,將小於 pivot 的放到左邊,將大於 pivot 的放到右邊,將 pivot 放到中間。經過這一步驟之後,陣列 p 到 r 之間的資料就被分成了三個部分,前面 p 到 q-1 之間都是小於 pivot 的,中間是 pivot,後面的 q+1 到 r 之間是大於 pivot 的。
占用太多額外的記憶體空間,我們就需要在 a[p…r]的原地完成分割槽操作。
我們通過游標 i 把 a[p…r-1]分成兩部分。a[p…i-1]的元素都是小於 pivot 的,我們暫且叫它「已處理區間」,a[i…r-1]是「未處理區間」。我們每次都從未處理的區間 a[i…r-1]中取乙個元素 a[j],與 pivot 對比,如果小於 pivot,則將其加入到已處理區間的尾部,也就是 a[i]的位置。
第一,快速排序是穩定的排序演算法嗎?
快速排序並不是乙個穩定的排序演算法。
第二,快速排序的時間複雜度是多少?
不管是最好情況、最壞情況,還是平均情況,時間複雜度都是 o(n
logn
)o(nlogn)
o(nlog
n)。第三,快速排序的空間複雜度是多少?
歸併排序不是原地排序演算法。
歸併排序的處理過程是由下到上的,先處理子問題,然後再合併。而快排正好相反,它的處理過程是由上到下的,先分割槽,然後再處理子問題。歸併排序雖然是穩定的、時間複雜度為 o(nlogn) 的排序演算法,但是它是非原地排序演算法。我們前面講過,歸併之所以是非原地排序演算法,主要原因是合併函式無法在原地執行。快速排序通過設計巧妙的原地分割槽函式,可以實現原地排序,解決了歸併排序占用太多記憶體的問題。
4, 2, 5, 12, 3 這樣一組資料,第 3 大元素就是 4。
我們選擇陣列區間 a[0…n-1]的最後乙個元素 a[n-1]作為 pivot,對陣列 a[0…n-1]原地分割槽,這樣陣列就分成了三部分,a[0…p-1]、a[p]、a[p+1…n-1]。如果 p+1=k,那 a[p]就是要求解的元素;如果 k>p+1, 說明第 k 大元素出現在 a[p+1…n-1]區間,我們再按照上面的思路遞迴地在 a[p+1…n-1]這個區間內查詢。同理,如果 k
尋找第K大的數(快排思想)
使用快排思想找第k大的數,演算法複雜度o n 1.以陣列a的第0位a 0 為參考基準base,將陣列劃分為兩個部分 如果找第k大的數,則將大於base的數往前挪,將小於base的數往後挪。如果找第k小的數,則與此相反。劃分過程與快排相同,使用兩個指標i和j分別指向陣列的首尾,根據指標所指元素與基準b...
基於快排思想的第 前 k大 小
演算法思路就是根據快排的partition,先隨機選擇乙個分隔元素 或a 0 將陣列分為 小於a p 的元素 a p 大於a p 的元素 如果這時候n p 1等於k的話,a p 就是所求的第k大,否則如果n p 1 k,那麼說明第k大元素應該是在 大於a p 的元素 裡,所以再partition這部...
快排的思想求第K小的數
描述輸入n 個數,m 次查詢。每次查詢給出乙個數x。要求 每次查詢輸出前 x個數中第 i小的數。i為第 i次查詢 你可以假設 m n xi xi 1 xi 2 xm xm n 輸入 line0 t line1 n,m line2 linen 1 num1,numn linen 2 linen 2 m...