快速排序
快速排序使用归并思想,对于子数组A[p..r],有如下三步分治过程:
- 分解:划分为A1[p..q-1]和A2[q+1..r],使得A1元素比A[q]小,A2元素比A[q]大
- 解决:递归调用快速排序,对分解的数组A1和A2进行排序
- 合并:因为子数组都是原址排序,不需要排序,数组A[p..r]已经有序
static void QuickSort(List<int> sq, int s, int e) { if (s < e) { int st = Partition(sq, s, e); QuickSort(sq, s, st-1); QuickSort(sq, st+1, e); } }
其中Partition部分将会选择一个元素作为主元(一般是最后一个),将元素分割两个部分,前边一部分小于主元,后边一部分大于主元
static int Partition(List<int> sq, int s, int e) { int pivotElement = sq[e]; int i = s - 1; for (int j = s; j < e; j++) { if (sq[j] <= pivotElement) { i++; int temp1 = sq[i]; sq[i] = sq[j]; sq[j] = temp1; } } i++; int temp = sq[i]; sq[i] = sq[e]; sq[e] = temp; return i; }
使用快速排序,在最坏的情况下为Θ(n^2),期望运行时间为Θ(nlg(n)).期望运行时间是在输入序列的所有排列都是等概率的,但工程中,并不总是成立,为此可以引入随机化。
随机化中,将随机的以为元素与最后一个元素交换。
static void RandomizedQuickSort(List<int> sq, int s, int e) { if (s < e) { int st = RandomizedPartition(sq, s, e); RandomizedQuickSort(sq, s, st - 1); RandomizedQuickSort(sq, st + 1, e); } } static int RandomizedPartition(List<int> sq, int s, int e) { int i = rand.Next(s, e); int temp = sq[i]; sq[i] = sq[e]; sq[e] = temp; return Partition(sq, s, e); }