快速排序算法幾種寫法。
首先快排的思想是選取一個數來劃分數組,這個數左邊的數都小於等於它,右邊的數都大於等於它。就這樣遞歸的劃分數組,最後達到快排的目的。
以下3種方法實現主要區別在於劃分數組操作不一樣,只要數組劃分好了,後面操作都一樣。
// 第一種方法,挖坑填坑方法。先選取數組第一個數作爲參考數,然後分別設置兩個指針i,j。i指向最左端,j指向最右端。首先把數組參考數所在位置挖掉作爲當前坑,此時坑所在位置及指針i指向的位置,然後指針 j 開始遍歷數組,直到遇到小於等於參考數的元素,將其挖出去填當前指針 i 指向的坑,此時更新新的坑,即指針 j 指向的坑,然後指針 i 向前遍歷數組元素,直到找到大於等於參考數的元素,然後將其挖出去填指針j 指向的坑,依次反覆,直到指針i與j相遇爲止,最後把參考數填最後一個坑。這就是一趟排序結果。
#include<iostream>
using namespace std;
void quicksort(int a[], int left, int right){
int index = a[left];//choose the left data as a index data
int i = left; //從左邊開始挖坑,i=left爲第一個坑
int j = right;//指向排序數的兩個指針
if (left >= right) //注意這裏遞歸結束標誌一定是劃分數組沒有元素爲止,只有一個元素返回時不行,因爲有可能越界情況出現
return ;
while (i < j){
while (a[j] > index && i < j)
--j;//從排序數組的右邊開始遍歷知道找到小於標誌位的數
if (i < j)
a[i] = a[j];//第j個位置挖坑,挖出來東西填第i個坑
while (a[i] <= index && i < j)
++i;
if (i < j)
a[j] = a[i];// 第i個位置挖出東西填第j個位置坑
}
a[j] = index;
// 上面的實現選取左邊第一個數爲劃分標誌位,標誌位左邊的數都小於它,右邊都大於等於它
quicksort(a,left,j-1);
quicksort(a,j+1,right);
}
int main(){
int a[]={9,2,3,7,4};
quicksort(a,0,4);
for (int i = 0; i < 5; ++i)
cout<<a[i]<<" ";
cout<<endl;
return 0;
}
第二種參考數歸位方法是從數組左端開始遍歷,選取數組最左端的元素作爲參考數,並把中點指針指向參考數所在位置,(中點指針指的是其左端的數均小於參考數,其自身及其右端的數均大於等於參考數)如果遇到小於參考數的元素,就將其與中點指針指向的元素交換,並將中點指針向前一步,這樣操作下去直到遍歷完數組。
#include<iostream>
using namespace std;
void swap( int *a, int*b){
int c;
c=*a;
*a=*b;
*b=c;
}
void quicksort(int a[], int left, int right){
int temp = a[left];// 選取左邊的數爲劃分數組的參考標準數
int j = left + 1;
int pivot = left; // pivot中間指針,pivot指針之前的數均小於參考數,pivot之後的數均大於等於參考數。
if (left < right){
while (j <= right){
if ( a[j] < temp){
swap(&a[j],&a[pivot]);
++pivot;
}
++j;
}
quicksort(a,left,pivot-1);
quicksort(a,pivot+1,right);
}
}
int main(){
int a[]={9,2,3,7,4};
quicksort(a,0,4);
for (int i = 0; i < 5; ++i)
cout<<a[i]<<" ";
cout<<endl;
return 0;
}
第一種和第二種方法主要區別就在比較次數不同,第二個相當於逐個冒泡遍歷方法,每次都要需要將大數冒泡到後移,增加交換次數,但是挖坑填洞方法比較次數較少,例如9,3,2,7,4一趟排序的話,第一種只需要交換一次,即4與9交換,一趟下來結構爲4,3,2,7,9;但是用第二種方法的話要把9往後冒泡,則交換4次,一趟結果爲3,2,7,4,9.
第三種方法不用遞歸實現。
未完