演算法基礎課四 排序演算法上

2021-10-04 23:22:49 字數 4426 閱讀 8008

常用的有:氣泡排序、插入排序、選擇排序、歸併排序、快速排序、計數排序、基數排序、桶排序

時間複雜度:

插入,冒泡,選擇排序:o ( n^2)

快排,歸併排序:o ( nlogn )

桶,計數,基數排序:o ( n )

有些排序演算法,時間複雜度,和原始資料的有序度相關,並且有穩定排序和不穩定排序,即排序後,是否改變了原來相等元素間的順序性;

舉例,訂單按金額排序,但要求相同金額的訂單,按照建立時間排序

所以,可以先按照建立時間排序,然後選擇穩定的排序演算法,按照金額排序,這樣就可以滿足要求

氣泡排序,是原地排序演算法,空間複雜度 o ( 1 ),每次迴圈,兩兩元素進行比較,將最大的元素不斷下沉,直到成為陣列末尾元素;

冒泡是穩定排序演算法,相等的元素,並不會交換次序,並且設計演算法時,在一次遍歷中,沒有元素交換,就可以認為資料已經有序,無需下次遍歷;

最壞時間複雜度:初始狀態的有序度是 0,要進行 n*

(n-1)/

2 次交換

最好時間複雜度:初始狀態的有序度是 n*

(n-1)/

2,一次遍歷,沒有元素交換,就結束排序

平均時間複雜度:使用概率論計算比較複雜,但可以通過有序度來粗略計算

取中間值 n*

(n-1)/

4 次交換

所以簡單統計,平均時間複雜度是 o ( n^

2)

插入排序,將集合分為排序區間,和未排序區間,每次都在未排序區間,選擇元素,插入到排序區間中,直到未排序區間為空,保證後插入的相同元素,放在前面插入相同元素的後面,所以是穩定的排序演算法;

空間複雜度是 o(1

) 最好時間複雜度是 o

(n):當每次都是在排序區間最後插入元素,插入時間複雜度是 o(1

) 最壞時間和平均時間複雜度是 o

(n^2

):每次插入時間複雜度是 o

(n) 平均時間複雜度:是每次向有序集合,插入乙個元素的平均時間複雜度是 o

(n),所以平均時間複雜度,是 o

(n^2

)

選擇排序,同樣將集合,分排序區間,未排序區間,每次從未排序區間,選擇最小元素,放在排序區間隊尾;

空間複雜度 o(1

) 最好,最壞,平均時間複雜度,都是 o

(n^2

),每次選擇時間複雜度都是 o

(n),共進行 n 次選擇

不穩定的排序演算法,因為每次都需要交換元素,就可能破壞了未排序區間元素的順序性

插入排序,應用更廣;

相比於氣泡排序,交換元素操作更簡單,氣泡排序需要三行**執行交換,插入只需一行

相比於選擇排序,插入是穩定性排序,而選擇排序不是

都使用分治思想,將大問題劃分為小問題來解決,都用遞迴來實現;

歸併排序,是將集合等分為兩個子集合,分別進行排序後,合併兩個有序子集合,然後子集合,同樣進行等分,排序,合併,如此遞迴,直到集合剩餘乙個元素;

遞推公式是 f

(p..

.q)=

merge(f

(p..

.r),

f(r.

..q)

),merge,合併兩個有序的陣列

終止條件是 p == r 或者 q == r

是穩定排序演算法,要求合併有序集合中,相同的元素,將前面集合先放入

遞迴**的時間複雜度,也使用遞迴來分析;

歸併時間複雜度 t

(n)=2*

t(n/2)

+ n,其中最後乙個 n 是合併兩個有序集合 n/

2 的時間複雜度

截至條件 t(1

)= c,c 是常量

t(n)=2

*(2*

t(n/4)

+ n/2)

+ n =4*

t(n/4)

+2*n =2^

(k)*

t(n/2^

(k))

+ kn,因為k次等分後 2

^k = n

最終得到 t

(n)= nlog2n + cn

所以歸併排序的時間複雜度是 o

(nlogn),並且沒有最好和最壞的區分,都需要遞迴這麼多次

歸併排序,與要排序的原始陣列的有序程度無關,其最好情況、最壞情況,還是平均情況,時間複雜度都是 o( nlogn ),並且空間複雜度是 o ( n ),這是其乙個缺點;

快速排序,每次從集合中,選取乙個基準數,進行資料交換,保證小於基準數的值放在基準數左邊,大於基準數的值放在基準值右邊,如此對基準值左邊集合,對基準值右邊集合,進行遞迴,直到根據基準數劃分後的子集合元素個數都為1;

// 排序a陣列,從p到r的元素,等於根據基準數交換資料後,分為小於基準數的p到q的元素,和大於基準數的q到r的元素

// 然後分別進行遞迴快速排序

遞推公式:fastsort

(a,p,r)

=fastsort

(a,p,q-1)

+fastsort

(a,q+

1,r)

終止條件是:p == r

quick_sort_c

(a, p, r)

根據基準值交換元素,需要不額外使用空間,選擇基準數後,分為兩個指標,依次從左往右和從右往左,左往右選擇比基準數大的值,右往左選擇比基準數小的值,兩個指標都找到後,進行交換,最後左右指標相遇,將相遇元素和基準值交換;

注意,這裡基準數的選擇,覺得了快排效率,簡單選擇最左邊,或者最右邊,更優化是三點選取,隨機選擇等

基準數如果選最左邊,要先從右往左進行查詢,因為這樣,最終左右指標相遇的點,是從左往右得到的,比基準數大,

且交換後的元素,即比基準數小,那麼最後一次交換,就是正確的,反之會最後是從右往左,比基準數小,且交換後

的元素,即比基準數大,這樣,是無法與最左邊的基準數交換,交換後就是錯誤的

快速排序,左右指標交換元素,會破壞相等元素的順序關係,所以是乙個不穩定的排序演算法;

快速排序,每次分割槽時間複雜度是 o

(n) 最好時間複雜度:每次都是等分,進行 log2n 次分割槽,所以最好時間複雜度是 o (nlogn)

最差時間複雜度:進行了 n 次分割槽,每次分割槽都是乙個元素 + 剩餘元素,所以最壞時間複雜度是 o

(n^2

) 平均時間複雜度是 o (nlogn);

快速排序的空間複雜度是 o (1),而歸併排序,空間複雜度是 o ( n ),這是快排應用廣的乙個原因;

在 o(n) 時間複雜度內,求無序陣列中的第 k 大元素,跟快排思路類似,基準值左邊放比基準值大的元素,那麼交換元素後,如果基準值下標是 k-1,那麼那麼就有 k-1 個元素比其大,基準值就為第 k 大元素,所以和快排演算法一致,只是左邊集合放大的元素,並且終止條件是 基準下標 q = k -1;

第 k 大的元素,即集合中只有 k-

1 個元素,比其大

按照快排的思路,選擇基準值,進行分割槽後,分割槽點是 p,要求比 a[p] 大,放集合左部分,

所以集合中,有 p 個元素,比 a[p] 大,如果 p =k-

1,那麼就要 k-

1 個元素比 a[p] da, a[p] 即為所求

如果 p > k-

1,那麼在左邊集合查詢

如果 p < k-

1,那麼在右邊集合查詢

如此遞迴,最終遞迴終止條件,p +

1= k

時間複雜度:第一次分割槽,需掃瞄全部資料,第二次分割槽,n/

2 資料,如此遞迴計算 n + n/

2+ n/4+

...+

1,n(

1/2)

^k =

1,得到 2

^k = n,等比數列求和 a(1

-q^n)/1

-q =n(

1-(1

/2)^k)/(

1-1/

2)=2n

(1-1

/n)=

2n -

2 所以時間複雜度是 o

(n)

如果有 10 個日誌檔案,每個大小約 300 m,每個檔案裡是按照時間從小到大排序的,希望將 10 個日誌檔案,合併為 1 個檔案,合併後仍然按照時間戳從小到大排列,要求演算法,使用空間只有 1gb,如何快速合併

典型的歸併排序,只不過排序 1gb 資料後,需要寫入磁碟

四 排序演算法

1.快速排序 procedure qsort l,r integer var i,j,mid integer begin i l j r mid a l r div 2 repeat while a i mid do dec j if i j then begin swap a i a j inc ...

Acwing演算法基礎課筆記(1 1)排序和二分

主要思想 上課學習內容 背過模板 課下 寫出模板題 做題目 課下 寫同一道題3 5次 快排 分治 確定分解點 q l q l r 2,q 隨機 調整區間 左邊所有數小於等於x,所以右邊數都大於等於x 遞迴處理左右兩段 樸素方法 1 a b 2 q l r q i x 放a q i x 放b 3 把a...

四 排序演算法 快速排序

快速排序的思想 選擇陣列中的乙個數作為中軸線,然後以這個中軸線為中心,大於中軸線的資料放到右邊,小於中軸線的資料放到左邊,然後每次比較完後再變中軸線的位置,不斷比較下去 include using namespace std template void quick sort t arry,int l...