快速排序是基於分治策略的排序算法,基本思想是,對於輸入的子數組a[p:r],按照以下三個步驟進行排序:
(1)分解:以元素a[p]爲基準元素,將a[p:r]中比元素a[p]小的元素移動到a[p]的左邊,比元素a[p]大的元素移動到a[p]的右邊,記錄分解完成後a[p]的下標q;
(2)遞歸求解:通過遞歸調用快速排序算法,分別對子數組a[p:q-1]和a[q+1:r]進行排序;
(3)合併:不需要合併算法,因爲排序是就地進行的。當遞歸完成後,數組就已經排好序.
#include <iostream>
using namespace std;
//劃分函數,以x爲基準將數組劃分成左右中三個部分,左邊都是比x小的,右邊都是比x大的,中間是x,返回x的下標
int Partition(int num[],int left,int right)
{
int x=num[left];
int i=left,j=right;
while(true)
{//2 2 /
while(num[i]<x)i++;//找到第一個比x大的元素
while(num[j]>x)j--;//找到第一個比x小的元素
if(i>=j)break;
int temp = num[i];
num[i]=num[j];
num[j]=temp;
if(num[i]==num[j]){i++;j--;} //如果兩者相等則跳過
for(int i=left;i<=right;i++)
cout<<num[i]<<" ";
cout<<endl;
}
return j;
}
void QuickSort(int num[],int left,int right)
{
if(left>=right)return;
int x = Partition(num,left,right);
QuickSort(num,left,x-1);
QuickSort(num,x+1,right);
}
int main()
{
int num[] = {5,100,9,10,2,18,6,80,51,2,35,6};
QuickSort(num,0,11);
for(int i=0;i<12;i++)
cout<<num[i]<<" ";
}
複雜性分析:最壞情況下劃分函數Partition每次執行需要O(n)時間,遞歸函數滿足T(n)=T(n-1)+O(n),解此遞歸方程可得T(n)=O(n^2);最好情況下,每次劃分所取的值都恰好是中值,即每次劃分產生兩個n/2的子區域,則T(n)=2T(n/2)+O(n),解此遞歸方程可得T(n)=O(n(logn);