2020竹C, jeeeerrrpop
給你一個長度為n的序列
你要把他們由小到大排序
先介紹基於比較、交換的演算法。
a, b = b, a
何謂演算法?
我們能自己想到排序演算法嗎?
void BubbleSort(int arr[], int n) {
for(int i = 0; i < n - 1; i++) {
for(int j = 0; j < n - i - 1; j++) {
if(arr[j] > arr[j + 1]) swap(arr[j], arr[j + 1]);
}
}
}
void SelectionSort(int arr[], int n) {
for(int i = 0; i < n - 1; i++) {
int min = i;
for(int j = i + 1; j < n; j++) {
if(arr[j] < arr[min]) min = j;
}
swap(arr[i], arr[min]);
}
}
void InsertionSort(int arr[], int n) {
for(int i = 1; i < n; i++) {
int j = i - 1;
while (j >= 0 && arr[j] > arr[j + 1]) {
swap(arr[j], arr[j + 1]);
j--;
}
}
}
Bubble Sort 若在迴圈執行時,判斷這一輪是否都沒有任何元素交換,可以把最優情況下的複雜度降低到 \(O(n)\)。
Insertion Sort 若把內層迴圈改成二分搜,就可以優化成 \(O(nlogn)\)。
有複雜度比 \(O(nlogn)\) 更好的排序方法嗎?
基於比較的排序演算法最好就是 \(O(nlogn)\)
const int size = 1000;
void CountingSort(int arr[], int n) {
int cnt[size] = {0};
for(int i = 0; i < n; i++) {
cnt[arr[i]]++;
}
int id = 0;
for(int i = 0; i < size; i++) {
while(cnt[i] > 0) {
arr[id] = i;
id++;
cnt[i]--;
}
}
}
時間複雜度是 \(O(n)\) 嗎?
k 為數字範圍
時間複雜度 \(O(n + k)\)
既然都有 \(O(nlogn)\) 的排序演算法了,那些\(O(n^2)\)的演算法根本不會被用到吧?
當序列長度不大的時候,Insertion Sort等等反而會比Quick Sort, Merge Sort還來得有效率。
reference
我不想自己寫SortQQ
std::sort
#include <algorithm>
int a[1000];
std::sort(a, a + 5);
酷酷的影片
Homework
neoj 2219