排序
稳定性的含义:如果数组中存在两个不同位置元素 x = y x=y x=y,排完序后原来的 x , y x,y x,y的相对位置发生了改变,则称这种排序是不稳定的(发生无意义的变换).
排序算法 | 最坏复杂度 | 平均复杂度 | 是否稳定 |
---|---|---|---|
插入排序 | O ( n 2 ) O(n^2) O(n2) | O ( n 2 ) O(n^2) O(n2) | 稳定 |
选择排序 | O ( n 2 ) O(n^2) O(n2) | O ( n 2 ) O(n^2) O(n2) | 不稳定 |
冒泡排序 | O ( n 2 ) O(n^2) O(n2) | O ( n 2 ) O(n^2) O(n2) | 稳定 |
快速排序 | O ( n 2 ) O(n^2) O(n2) | O ( n log n ) O(n\log n) O(nlogn) | 不稳定 |
归并排序 | O ( n log n ) O(n\log n) O(nlogn) | O ( n log n ) O(n\log n) O(nlogn) | 稳定 |
堆排序 | O ( n log n ) O(n\log n) O(nlogn) | O ( n log n ) O(n\log n) O(nlogn) | 不稳定 |
基数排序 | O ( d ( r + n ) ) O(d(r+n)) O(d(r+n)) | O ( d ( r + n ) ) O(d(r+n)) O(d(r+n)) | 稳定 |
基数排序中的 r r r表示基数, d d d表示位数.
R a d i x    S o r t Radix\; Sort RadixSort:
#include <cstdio>
const int MAXN = 1e5 + 10;
const int r = 13;
int n, cnt[r], a[MAXN], t[MAXN];
void radix_sort() {
int maxa = 0;
for(int i = 1; i <= n; i ++)
if(maxa < a[i]) maxa = a[i];
int d = 1, w;
for(; d <= maxa; d *= r) {
for(int i = 0; i < r; i ++) cnt[i] = 0;
for(int i = 1; i <= n; i ++) {
w = a[i] / d % r;
++ cnt[w];
}
for(int i = 1; i < r; i ++) cnt[i] += cnt[i - 1];
for(int i = n; i; i --) {
w = a[i] / d % r;
t[cnt[w] --] = a[i];
}
for(int i = 1; i <= n; i ++) a[i] = t[i];
}
}
int main() {
scanf("%d", &n);
for(int i = 1; i <= n; i ++)
scanf("%d", &a[i]);
radix_sort();
for(int i = 1; i <= n; i ++)
printf("%d%c", a[i], " \n"[i == n]);
return 0;
}
Q u i c k    S o r t Quick \; Sort QuickSort:
#include <cstdio>
const int MAXN = 1e5 + 10;
void swap(int & a, int & b) {
if(a ^ b) a ^= b ^= a ^= b;
}
int n, a[MAXN];
void qsort(int l, int r) {
if(l >= r) return ;
int mid = a[l + r >> 1], i = l, j = r;
do {
for(; a[i] < mid; ++ i) ;
for(; a[j] > mid; -- j) ;
if(i <= j) swap(a[i ++], a[j --]);
} while(i <= j) ;
qsort(l, j);
qsort(i, r);
}
int main() {
scanf("%d", &n);
for(int i = 1; i <= n; i ++)
scanf("%d", &a[i]);
qsort(1, n);
for(int i = 1; i <= n; i ++)
printf("%d%c", a[i], " \n"[i == n]);
return 0;
}
主定理
这里大概介绍一下主定理,符号和语言可能不严谨.
如果某算法的计算时间可以用一下递推式表示: T ( n ) = a T ( n b ) + f ( n ) T(n)=aT(\frac{n}{b})+f(n) T(n)=aT(bn)+f(n)
多项式大于感性理解为:它们的商大于一个多项式。即 ∃    e > 0 , e ∈ R ∃\;e>0,e\in R ∃e>0,e∈R,使得 f ( x ) > g ( x ) ∗ n e f(x)>g(x)*n^e f(x)>g(x)∗ne
例如 n 1.1 > n n^{1.1}>n n1.1>n,但是 n ̸ < n log n n \not < n \log n n̸<nlogn.
(1) 若 f ( n ) < n log b a f(n) < n^{\log_b^a} f(n)<nlogba,则 T ( n ) = O ( n log b a ) T(n)=O(n^{\log_b^a}) T(n)=O(nlogba)
(2) 若 f ( n ) = n log b a f(n) = n^{\log_b^a} f(n)=nlogba,则 T ( n ) = O ( n log b a log n ) T(n)=O(n^{\log_b^a}\log n) T(n)=O(nlogbalogn)
(3) 若 f ( n ) > n log b a f(n) > n^{\log_b^a} f(n)>nlogba,则 T ( n ) = O ( f ( n ) ) T(n)=O(f(n)) T(n)=O(f(n))
例1(NOIP 2017 提高组初赛): T ( N ) = 2 T ( N 2 ) + N log N T(N)=2T(\frac{N}{2})+N \log N T(N)=2T(2N)+NlogN,则时间复杂度为:
f ( n ) = N log N f(n)=N \log N f(n)=NlogN, N log b a = N N^{\log_b^a}=N Nlogba=N, N log N = N N \log N=N NlogN=N,因此 T ( N ) = O ( N log 2 N ) T(N)=O(N\log^2 N) T(N)=O(Nlog2N).