1.說明
這個快速排序演算法是對前面的 快速排序演算法QuickSort 一種改進。
只是修改了int Partition(int arry[],int start,int end)這個方法。
2.思路
仔細觀察我們可以發現,我們前面Partition方法中,都需要swap(arry,start,end), 但是這一步中有些步驟是可以省略的。
在(<-end)過程中,碰到第一個小於等於pivot的元素時,只需要進行一次賦值arry[start]=arry[end]; 因為當前的arry[start]是值就是pivot ;
在(start->)過程中,碰到第一個大於等於pivot的元素之,只需要進行一次賦值arry[end]=arry[start]; 因為當前的arry[end]的值就是pivot的值。
整個過程中,不是start就是end指向pivot所儲存的單元 ,所以在整個過程中,pivot沒有必要每次通過swap來儲存,只需要在最後找到pivotkey的時候, 令arry[pivotkey]=pivot即可。
具體修改如下代碼執行個體。
3.改進的快速排序QuickSortView Code
#include<iostream>
#include<stdlib.h>
#include<time.h>
using namespace std;
#define maxNum 100
/*
改進的int Partition(int arry[],int start,int end)
仔細觀察我們可以發現,我們前面Partition方法中,都需要swap(arry,start,end),
但是這一步中有些步驟是可以省略的。
在(<-end)過程中,碰到第一個小於等於pivot的元素時,只需要進行一次賦值arry[start]=arry[end];
因為當前的arry[start]是值就是pivot
在(start->)過程中,碰到第一個大於等於pivot的元素之,只需要進行一次賦值arry[end]=arry[start];
因為當前的arry[end]的值就是pivot的值,
整個過程中,不是start就是end指向pivot所儲存的單元
所以在整個過程中,pivot沒有必要每次通過swap來儲存,只需要在最後找到pivotkey的時候,
令arry[pivotkey]=pivot即可。
*/
int Partition(int arry[],int start,int end)
{
//cout<<"軸心數組"<<endl;
//for(int i=start;i<=end;i++)
// cout<<arry[i]<<" ";
//cout<<endl;
int pivot=arry[start];
while(start<end)
{
while(arry[end]>pivot&&start<end)
end--;
arry[start]=arry[end];
while(arry[start]<pivot&&start<end)
start++;
arry[end]=arry[start];
}
arry[start]=pivot;
/*cout<<"輸出軸心位置:"<<start<<endl;*/
return start;
}
void QSort(int arry[],int start,int end)
{
if(start<end)
{
int pivotkey=Partition(arry,start,end);
QSort(arry,start,pivotkey-1);
QSort(arry,pivotkey+1,end);
}
}
void QuickSort(int arry[],int len)
{
QSort(arry,1,len);
}
void main()
{
int n;
int arry[maxNum]={0};
srand(time(NULL));
cout<<"輸入隨機數組長度n:"<<endl;
cin>>n;
cout<<"產生長度為"<<n<<"的100以內的隨機數組"<<endl;
cout<<"排序前:"<<endl;
for(int i=1;i<=n;i++)
{
arry[i]=rand()%100;
cout<<arry[i]<<" ";
}
cout<<endl;
QuickSort(arry,n);
cout<<"排序後:"<<endl;
for(int i=1;i<=n;i++)
{
cout<<arry[i]<<" ";
}
cout<<endl;
system("pause");
}
/*
輸入隨機數組長度n:
10
產生長度為10的100以內的隨機數組
排序前:
91 67 99 37 40 70 49 71 43 42
排序後:
37 40 42 43 49 67 70 71 91 99
請按任意鍵繼續. . .
*/
PS:2012-5-4
今天發現以前一直以為對的快排寫錯了,因此沒有考慮需要排序的數相等的情況,如果排序的數組中有相同的數,那麼就會出現死迴圈,一直沒有結果,要做的修改就是修改Partition函數,修改以後如下:
View Code
int Partition(int arry[],int start,int end){ //cout<<"軸心數組"<<endl; //for(int i=start;i<=end;i++) // cout<<arry[i]<<" "; //cout<<endl; int pivot=arry[start]; while(start<end) { while(arry[end]>=pivot&&start<end) end--; arry[start]=arry[end]; while(arry[start]<=pivot&&start<end) start++; arry[end]=arry[start]; } arry[start]=pivot; /*cout<<"輸出軸心位置:"<<start<<endl;*/ return start;}
做的唯一修改就是將原來的arry[end]>pivot改為arry[end]>=pivot,arry[start]<pivot改為arry[start]<=pivot
快排練習(PS:2012-10-2)View Code
#include<iostream>#include<stdlib.h>using namespace std;int Partition(int arry[],int start,int end){ int pivot=arry[start]; while(start<end) { while(start<end&&arry[end]>=pivot)//找到第一個小於pivot的元素為止,如果arry[end]>=pivot則過濾掉 end--; arry[start]=arry[end]; while(start<end&&arry[start]<=pivot)//找到第一個大於pivot的元素為止 start++; arry[end]=arry[start]; } arry[start]=pivot; return start;//此時start=end,所以返回start跟返回end一樣。}void QuickSort(int arry[],int start,int end){ if(start>=end) return; int pivotkey=Partition(arry,start,end); QuickSort(arry,start,pivotkey-1); QuickSort(arry,pivotkey+1,end);}void PrintArry(int arry[],int len){ for(int i=0;i<len;i++) cout<<arry[i]<<" "; cout<<endl;}int main(){ int arry[]={1,2,3,2,2,2,5,4,2}; int len=sizeof(arry)/sizeof(int);//求數組長度 QuickSort(arry,0,len-1);//快排 PrintArry(arry,len);//列印數組 system("pause"); return 0;}