# 排序(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());
```
只能小於(<),不能大於(>)。