Skip to content

排序sort

資料來源:https://openhome.cc/zh-tw/algorithm/sort/abc/

選擇排序

如果排序是由小而大,從後端未排序部份選擇一個最小值,並放入前端已排序部份的最後一個(和前面 swap)。例如排序前 70、80、31、37、10、1、48、60、33、85。

\[
1
\]

80 31 37 10 70 48 60 33 85(選出最小值 1,1與70交換)

\[
1 10
\]

31 37 80 70 48 60 33 85(選出最小值 10,10與80交換)

\[
1 10 31
\]

37 80 70 48 60 33 85(選出最小值 31)

\[
1 10 31 33
\]

80 70 48 60 37 85(選出最小值 33,33與37交換)

\[
1 10 31 33 37
\]

70 48 60 80 85(選出最小值 37,37與80交換)

\[
1 10 31 33 37 48
\]

70 60 80 85(選出最小值 48,48與70交換)

\[
1 10 31 33 37 48 60
\]

70 80 85(選出最小值 60,60與70交換)

\[
1 10 31 33 37 48 60 70
\]

80 85(選出最小值 70)

\[
1 10 31 33 37 48 60 70 80
\]

85(選出最小值 80)

\[
1 10 31 33 37 48 60 70 80 85
\]

(選出最小值 85)

插入排序

每次從後端未排序部份取得最前端的值,然後插入(往前 swap)前端已排序部份的適當位置。例如排序前 92、77、67、8、6、84、55、85、43、67。

\[
77 92
\]

67 8 6 84 55 85 43 67(將 77 插入 92 前)

\[
67 77 92
\]

8 6 84 55 85 43 67(將 67 插入 77 前)

\[
8 67 77 92
\]

6 84 55 85 43 67(將 8 插入 67 前)

\[
6 8 67 77 92
\]

84 55 85 43 67(將 6 插入 8 前)

\[
6 8 67 77 84 92
\]

55 85 43 67(將 84 插入 92 前)

\[
6 8 55 67 77 84 92
\]

85 43 67(將 55 插入 67 前)

\[
6 8 55 67 77 84 85 92
\]

43 67(將 85 插入 92 前)

\[
6 8 43 55 67 77 84 85 92
\]

67(將 43 插入 55 前)

\[
6 8 43 55 67 67 77 84 85 92
\]

(將 67 插入 77 前)

氣泡排序

排序時若是從小到大,以比較相鄰元素的方式,將較大元素交換至右端,較大的元素會不斷往右移動,像是氣泡一樣,直到適當位置為止。例如排序前 95、27、90、49、80、58、6、9、18、50。

27 90 49 80 58 6 9 18 50

\[
95
\]

(95 浮出)

27 49 80 58 6 9 18 50

\[
90 95
\]

(90 浮出)

27 49 58 6 9 18 50

\[
80 90 95
\]

(80 浮出)

27 49 6 9 18 50

\[
58 80 90 95
\]

(58 浮出)

27 6 9 18 49

\[
50 58 80 90 95
\]

(50 浮出)

6 9 18 27

\[
49 50 58 80 90 95
\]

(49 浮出)

6 9 18

\[
27 49 50 58 80 90 95
\]

(27 浮出)

6 9

\[
18 27 49 50 58 80 90 95
\]

(18 浮出)

6

\[
9 18 27 49 50 58 80 90 95
\]

(9 浮出)

\[
6 9 18 27 49 50 58 80 90 95
\]

(6 浮出)

氣泡排序法可以利用旗標方式稍微減少比較時間,當尋訪完未排序部份都沒有發生任何交換動作,表示排序已經完成,不再進行後續的比較與交換動作。

merge sot 合併演算法

時間複雜度 O(log n)
影片來源:https://www.youtube.com/watch?v=C9Xes8wH6Co

自定義順序

一、
先宣告一個陣列int v[n]={6,4,3,5,8},共n=5項。
二、
把a想成左邊(前一項),b想成右邊(後一項),回傳是最後結果(左邊>右邊)

Danger | 口訣

cmp(a, b) 回傳 true,代表 a 應該排在 b 前面(左邊)。

#include <bits/stdc++.h>
using namespace std;
bool cmp(int a,int b){
    return a>b;
}

int main(){
    int v[10]={6,4,3,5,8};
    sort(v,v+5,cmp);
    for(int i=0;i<5;i++){
        cout<<v[i]<<" ";
    }
}
8 6 5 4 3

Danger | 要注意不能讓cmp變數x、y資料型態為auto,會錯誤


也可以多個欄位,如下

#include <bits/stdc++.h>
using namespace std;
struct st{
    int x;
    int y;
}v[10];
bool cmp(st a,st b){
    return a.y>b.y;
}
int main(){
    istringstream cin("6 4 3 5 8 7");

    for(int i=0;i<3;i++){
        cin>>v[i].x>>v[i].y;
    }
    sort(v,v+3,cmp);
    for(int i=0;i<3;i++){
        cout<<v[i].x<<" "<<v[i].y<<"\n";
    }
}
8 7
3 5
6 4

以上是按照v[]中每個st元素的y為依據,一樣不能用auto為型態