排序
稳定性的含义:如果数组中存在两个不同位置元素x=yx=yx=y,排完序后原来的x,yx,yx,y的相对位置发生了改变,则称这种排序是不稳定的(发生无意义的变换).
排序算法 | 最坏复杂度 | 平均复杂度 | 是否稳定 |
---|---|---|---|
插入排序 | O(n2)O(n^2)O(n2) | O(n2)O(n^2)O(n2) | 稳定 |
选择排序 | O(n2)O(n^2)O(n2) | O(n2)O(n^2)O(n2) | 不稳定 |
冒泡排序 | O(n2)O(n^2)O(n2) | O(n2)O(n^2)O(n2) | 稳定 |
快速排序 | O(n2)O(n^2)O(n2) | O(nlogn)O(n\log n)O(nlogn) | 不稳定 |
归并排序 | O(nlogn)O(n\log n)O(nlogn) | O(nlogn)O(n\log n)O(nlogn) | 稳定 |
堆排序 | O(nlogn)O(n\log n)O(nlogn) | O(nlogn)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)) | 稳定 |
基数排序中的rrr表示基数,ddd表示位数.
Radix  SortRadix\; SortRadixSort:
#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;
}
Quick  SortQuick \; SortQuickSort:
#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)=aT(nb)+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)∗nef(x)>g(x)*n^ef(x)>g(x)∗ne
例如n1.1>nn^{1.1}>nn1.1>n,但是n̸<nlognn \not < n \log nn̸<nlogn.
(1) 若f(n)<nlogbaf(n) < n^{\log_b^a}f(n)<nlogba,则T(n)=O(nlogba)T(n)=O(n^{\log_b^a})T(n)=O(nlogba)
(2) 若f(n)=nlogbaf(n) = n^{\log_b^a}f(n)=nlogba,则T(n)=O(nlogbalogn)T(n)=O(n^{\log_b^a}\log n)T(n)=O(nlogbalogn)
(3) 若f(n)>nlogbaf(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)=2T(N2)+NlogNT(N)=2T(\frac{N}{2})+N \log NT(N)=2T(2N)+NlogN,则时间复杂度为:
f(n)=NlogNf(n)=N \log Nf(n)=NlogN,Nlogba=NN^{\log_b^a}=NNlogba=N,NlogN=NN \log N=NNlogN=N,因此T(N)=O(Nlog2N)T(N)=O(N\log^2 N)T(N)=O(Nlog2N).