排序
插入排序
for (int j=2; j<A.size(); ++j){
auto key = A[j];
for (int i = j-1; i>0 && A[i]>key; --i)
A[i + 1] = A[i];
A[i + 1] = key;
}
- 循环不变量:每次循环开始前,子数组 A[1..j-1] 有序
- worst: $\Theta(n^2)$
- average: $\Theta(n^2)$
归并排序
void merge_sort(vector<int>& A, int l, int r){
if (l < r){
int mid = (l+r)/2;
merge_sort(vector<int>& A, l, mid);
merge_sort(vector<int>& A, mid, r);
merge(A, l, mid, r); // O(r-l)
}
}
- worst case: $\Theta(n\lg n)$
- average case: $\Theta(n\lg n)$
堆排序
build_max_heap(A)
for i in range(A.length, 1, -1):
swap(A[1], A[i])
A.size -= 1
max_heapify(A, 1)
- worst case: $O(n\lg n)$
- not stable
快速排序
def partition(A, p, r):
x = A[r]
while (1):
while (a[i] < x) i+=1
while (a[j] > x) j-=1
if (i>=j) break
swap(a[i], a[j])
swap(A[r], A[j])
return j
def quicksort(A, p, r):
if p<r:
q = Partition(A, p, r)
quicksort(A, p, q-1)
quicksort(A, q+1, r)
- worst case: $\Theta(n^2)$
- average: any split of constant yields $O(n\lg n)$
- expected: $\Theta(n\lg n)$
- $X_{ij}=[z_i \text{ compared to } z_j]$
- $P(z_i \text{ compared to } z_j)=\frac{2}{j-i+1}$
- not stable
线性排序
- Counting sort: $\Theta(k+n)$ (range 0 to k)
- Radix sort: $\Theta(d(n+k))$ (d digits up to k values)
- Bucket sort: worst $\Theta(n^2)$, average $O(n)$ (distributed uniformly and independently over [0,1))
Order statics
快排修改
def random_select(A, p, r, i):
if p==r:
return A[p]
q = random_partion(A, p, r)
k = q - p + 1
if i==k:
return A[q]
elif i<k:
return random_select(A,p,q-1,i)
else
return random_select(A,q+1,r,i-k)
- worst: $\Theta(n^2)$
- expected: $O(n)$
方法二
def select(A, p, r, i):
if p==r:
return A[p]
# Get divide point
A_m = []
for i in range(p, r, 5):
A_m += [median(A, i, i+5)]
q = select(A_m, 0, len(A_m), (r-q+1)/2)
# Partiion on q
k = partion_on_q(A, p, r, q)
if i == k:
return x
elif i < k:
select(A, p, k-1, i)
else:
select(A, k+1, r, i-k)
- worst: $O(n)$
- $T(n)\leq T(\lceil\frac{n}{5}\rceil)+T(3(\lceil\frac{1}{2}\lceil\frac{n}{5}\rceil\rceil - 2))+ O(n)$