---
# System prepended metadata

title: 排序(sort)

---

# 排序(sort)
排序，就是按照一種關係做排列，譬如說由小到大、由大到小。
排序有很多方法，著名的就有：氣泡排序、合併排序、選擇排序，基本上不會有人手刻這些排序法，單純只為了排序，因為有函式可以用，那就來看怎麼用。
## sort函式
### 如何排序
```cpp=
int a[5] = {3, 4, 1, 2, 4};
sort(a, a + 5);
```
兩個都要寫要排序的資料，第一個擺包含的起始位置，第二個擺後一個位置，(其實就是擺陣列的長度啦），那還有$std::vector$的用法：
```cpp=
vector<int> v;
sort(v.begin(), v.end());
```
當然也可以由大到小：
```cpp=
vector<int> v;
sort(v.begin(), v.end(), greater<int>());
```
有趣的是內建的有小到大是 $!greater<int>()$，所以一般都沒在寫的。

### 內建的排序機制
其中排序的型態可以有很多種譬如 $pair$，如果pair的兩個形態相同，會有內建的比較方式：會先比較第一個key在比較第二個key。

| key 1 | key 2 | 
| -------- | -------- |
| 1  | 4    |
| 1    | 7     |
| 2   | 3     |
| 4    | 1     |

以上就是$pair<int, int>$ 做完排序的樣子，所以key 1一定是遞增，key 2就很不一定了。
```cpp=
vector<pair<int, int>> v = {{2, 3}, {1, 4}, {4, 1}, {1, 7}};
sort(v.begin(), v.end());
```
### 時間複雜度？
$O(N\log N)$
## 自訂排序
我們常會希望資料要按照一定的方式儲存在資料結構裡，有時候不僅僅是由小到大，甚至裡面放 $struct$ 最好都會寫自定排序。
### 比較函式(cmp)
以由小到大舉例：
```cpp=
vector<int> v;
bool cmp(const int &a, const int &b){
    return a < b;
}
sort(v.begin(), v.end(), cmp);
```
先寫一個布林函式(const跟&可以不用加),接著$return$，裡面就放著你想要的兩個數之排列方式。最後，$sort$的第三項擺$cmp$就好了
### 練習
稍微練習一下：

$給你 𝑁 個正整數，將奇數排在前方，偶數排在後面法，
如果奇偶相同數字就小的排在前面。$

先想你想要怎麼排序，奇數放前面就代表我要奇數，所以$cmp$就可以這樣寫：
```cpp=
bool cmp(const int &a, const int &b){
    if(a % 2 != b % 2) return a % 2;
    return a < b;
}
```
基本上如果$cmp$裡面只有$if, else,$ 運算符號，時間複雜度依舊是$O(N\log N)$

有空可以寫寫2023TOI初選的pA...
## struct自訂排序
剛剛前面提及相同型態的資料有內建的排序，但如果我們直接執行以下程式碼：
```cpp=
struct point{
    int x, y;
};
vector<point> v = {{2, 3}, {1, 4}, {4, 1}, {1, 7}};
sort(v.begin(), v.end());
```
你會發現，幹根本執行不了。好，所以怎麼辦，假設我們要排成跟內建方法一樣的排序，有兩種方法：
1. $cmp$ 
```cpp=
struct point{
    int x, y;
};
bool cmp(const point &a, const point &b){
    if(a.x != b.x) return a.x < b.y;
    return a.y < b.y;
}
vector<point> v = {{2, 3}, {1, 4}, {4, 1}, {1, 7}};
sort(v.begin(), v.end(), cmp);
```
2. 自訂比較運算符號

$struct$ 之所以不能直接sort，是因為兩個 $struct$ 沒有天身賦予它的比較關係，既然沒有，那就自訂吧！
```cpp=
struct point{
    int x, y;
    bool operator<(const point &a) const {
        if(x != a.x) return x < a.x;
        return y < a.y;
    }
};
vector<point> v = {{2, 3}, {1, 4}, {4, 1}, {1, 7}};
sort(v.begin(), v.end());

```
只能小於(<)，不能大於(>)。