1. 簡述
假設待排序數組為 int array[], 數組長度為n。快速排序是一個遞迴得方法。
當n==1的時候,停止排序。
當n>1的時候,首先選擇數組中得一個元素作為基準,然後,把小於這個基準得元素放到這個基準的左邊,把大於這個基準得元素放到這個元素得右邊。
具體實現下面進行簡單得說明,假設array[0]作為基準:
首先,儲存基準得值,int tmp=array[0];
然後,兩個指標,int left=0; int right = n-1;
bool flag_left = false; // 初始從右邊開始
while(left < right) {
if(flag_left == true) {
如果當前值小於基準,則left++;
否則,array[right]=array[left]; right--; flag_left = false;
}
else {
如果當前值大於基準,則right--;
否則,array[left]=array[right]; left++; flag_left = true;
}
}
array[left] = tmp;
上面這段代碼中,當輪到left指標執行時,right指標向的位置是可以使用的。當輪到right指標執行時,left指標指向的位置是可以使用的。
初始時,備份了array[0],left指標指向的位置是可以使用 得,因此從右邊開始。
最後,遞迴排序array[0]-array[left-1]和array[left+1]-array[n-1]兩個部分的數組。
2. 複雜度
平均時間複雜度是O(N*logN)。當數組本身已經有序得情況下,需要比較得次數是N*N次。為瞭解決這樣的問題,可以使用亂數快速排序,即每次基準是隨即選擇的。
穩定性屬於非穩定排序。因為在與基準的比較過程中的交換很可能打破已有的順序。
3. 代碼
void quick_sort(int array[], int n) {
if(n <= 1)
return;
int tmp = array[0];
int left = 0; int right = n-1;
bool left_flag = false;
while(left < right) {
if(left_flag == true) { // 當前left指標
if(array[left] < tmp) {
left++;
}
else {
array[right] = array[left];
right--;
left_flag = false;
}
}
else { // 當前right指標
if(array[right] > tmp) {
right--;
}
else {
array[left] = array[right];
left++;
left_flag = true;
}
}
}
array[left] = tmp;
quick_sort(array, left); // array[0]-array[left-1]
quick_sort(array+left+1, n-left-1); // array[left+1], array[n-1]
}
實際上,快速排序是作為冒泡排序的改進提出來的,很多實現都是通過元素交換實現的,上面的代碼是改進後的,更加有效率,把元素交換變成了元素的賦值。
一般來說,交換排序包括:冒泡排序和快速排序。
下面貼一個快速排序使用交換元素的實現:
void quicksort(int arr[],int beg,int end) {
if (end >= beg + 1) {
int piv = arr[beg], k = beg + 1, r = end; // 從基準(array[0])右邊的元素開始掃描,對於小於基準的元素跳過,對於大於基準的元素,交換到右邊的位置上去,縮減右邊的位置。 // 當右邊可以交換的位置與當前元素重疊了,結束迴圈
while (k < r) { if (arr[k] < piv)
k++;
else
swap(&arr[k], &arr[r--]);
} // 交換基準
if (arr[k] < piv){ swap(&arr[k],&arr[beg]);
quicksort(arr, beg, k);
quicksort(arr, r, end);
} else {
if (end - beg == 1)
return;
swap(&arr[--k],&arr[beg]);
quicksort(arr, beg, k);
quicksort(arr, r, end);
} }
}
4. 參考資料
維基百科-快速排序 http://en.wikipedia.org/wiki/Quicksort