快速排序,Quick Sort。
采用了经典的分治思想:每次确定一个元素的位置,并将序列分为两个子序列:小于等于该元素、大于等于该元素。问题转为分别对刚得到的两个序列进行处理,直到序列长度为1.
Partition函数是比较重要的,这里采用了和算法导论类似的想法:每次随机从中抽取一个元素A,将其与序列尾部元素交换。从头向后扫描,保存两个index:small、index。small逐渐加一,标识比A小的元素应放的坐标。index向后扫描,每当发现小于A的元素,就令small+1,并交换index 和 small所指元素。最后交换small+1和A(即序列尾部元素)。
最后用递归实现分治。参考代码如下(代码参考自《剑指Offer》以及《算法导论》):
#include<iostream> #include<ctime> #include<cstdlib> using namespace std; int Partition(int *a, int length, int start, int end) { if (a == NULL || start<0 || end>=length) { return -1; } srand(time(NULL)); int index = rand()%(end-start)+start; swap(a[index], a[end]); int small = start - 1; for (index = start; index <= end; index++) { if (a[index] < a[end]) { small++; if (index!=small) swap(a[small], a[index]); } } small++; swap(a[small], a[end]); return small; } void QSort(int* a, int length, int start, int end) { if (start == end) return; int p = Partition(a, length, start, end); if (p > start) QSort(a, p-start , start, p - 1); if (p < end) QSort(a, end-p, p + 1, end); } void Print(int *a, int len) { for (int i = 0; i < len; i++) cout << a[i] << " "; } int main() { srand(time(NULL)); const int maxLen=10; const int maxNum = 1000; int *a = new int[maxLen]; for (int i = 0; i < maxLen; i++) { a[i] = rand() % maxNum; } QSort( a , maxLen, 0, maxLen - 1); Print(a, maxLen); cout << endl; return 0; }