快速排序,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;
}