快速排序 :
原理:
快速排序法采用 “ 分而治之 ” 的方法,把一个串行分为两个串行。
排序过程:
- 从数列中挑出一个元素,称为 “基准”(pivot);
- 重新排序数列,所有元素比基准值小的摆放在基准前面,所有元素比基准值大的摆在基准的后面(相同的数可以到任一边)。在这个分区退出之后,该基准就处于数列的中间位置。这个称为分区(partition)操作;
- 递归地(recursive)把小于基准值元素的子数列和大于基准值元素的子数列排序;
注意:
- 选取基准:
选取基准的方法:取 头、中、尾 的中位数。
这里,我们选用Median3函数来实现此方法。在下方的代码中将会具体介绍。 - 子集划分:
当进行上面的排序过程的 2 操作时,如果有元素正好等于 基准 ,停下来做交换比较好。
例如:对 3、13、10、4、9进行排序。
代码如下:
#include <iostream>
using namespace std;
int N=8;
int A[8];
int Pivot;
int Median3(int A[],int left,int right) /*选取基准, 取 头、中、尾 的中位数。*/
{
int center=(left+right)/2;
if( A[left] > A[center] ) swap( A[left] , A[center]);
if( A[left] > A[right] ) swap( A[left] , A[right]);
if( A[center] > A[right] ) swap( A[center] , A[right]);
/*使得 A[left]<=A[center]<=A[right]*/
swap( A[center] , A[right]); /*将基准放到右边*/
/*因为在上面的三个if判断里,已经作出了三者的排序,
所以,只需要考虑A[left+1]至A[right-1]之间的数*/
return A[right];
}
void Quick_Sort (int A[],int left,int right)
{
Pivot=Median3(A , left ,right);
int i=left,j=right-1;
for(; ;)
{
while (A[i] < Pivot) i++;
while (A[j] > Pivot) j--;
if(i<j) swap(A[i],A[j]);
else break;
}
swap(A[i],A[right]);
if(left<i-1) Quick_Sort(A,left,i-1); /*递归地把小于基准的元素进行排序*/
if(right>i+1) Quick_Sort(A,i+1,right); /*递归地把大于基准的元素进行排序*/
}
int main()
{
for(int i=0;i<N;i++) cin >> A[i];
Quick_Sort(A,0,N-1);
for(int i=0;i<N;i++) cout << A[i]<<endl;
return 0;
}
ADDITION:
- 快速排序使用的是递归,对于小规模的数据(例如N不到100)可能还不如插入排序快。
- 因此,当递归的数据规模充分小,则停止使用递归,直接使用简单排序。
- 时间复杂度:O(n logn) O(n^2);
- 稳定性:不稳定。
各种排序比较 :