1. 程式人生 > >快速排序(quick sort)

快速排序(quick sort)

前面兩個小節,我們分別介紹了氣泡排序插入排序,在我們本節講解一種更加高效的排序方法,快速排序,也即是常說的快排。

1、演算法思想

實際上,快排是對氣泡排序的一種改進,採用分而治之的思想。
在待排序表 A[1,2…n]中選取一個基準值pivot(通常選取序列首元素);
通過一趟排序操作將待排序表分為獨立的兩部分A[1,2…k-1],A[k+1,…n]。
其中A[1,2…k-1]都是比基準值小的元素,A[k+1,…n]都是比基準值大的元素。

而基準值pivot通過一趟排序確定了最終的位置,然後就是對A[1,2…k-1], A[k+1,…n]這兩部分,遞迴的進行上述操作。

2、優缺點

優點
平均時間資源消耗O(nlogn) 沒有氣泡排序插入排序大。
有很多優化方法,如遞迴劃分得到的子序列的規模較小的時候,不要再遞迴呼叫快排,或者儘量選取一個可以講資料中分的基準元素。
缺點:
需要額外的空間來儲存遞迴的資訊,平均空間複雜度O(logn)
不穩定,可能會使得某些元素的相對位置發生變化。

3、關鍵點

主要操作兩部分:根據基準元素劃分塊,在劃分的塊上進行遞迴操作。
無論是劃分塊操作,還是在塊上進行排序的操作,都用到兩個控制變數,left 和 right。(控制結束,當兩個變數相遇的時候結束)
每一趟排序後將一個元素(基準元素)放到最終的位置上

4、程式程式碼(c++)

例子:輸入一個有10個元素的陣列,並對其進行快速排序,最後陣列為升序。

/* quick sort */
# include<iostream>
using namespace std;
void quicksort(int[], int, int);
int partition(int[], int, int);
int main()
{
    int array [] = {55,2,6,4,32,12,9,73,26,37};

    int len = sizeof(array) / sizeof(int);

    cout<<"輸入的原始序列:  "
; for(int i=0; i<len; i++) // 輸出原序列 cout<<array[i]<<","; cout<<endl<<endl; quicksort(array,0, len-1); // 呼叫排序函式 cout<<" ----快速排序結果---- " << endl; for(int i=0; i<len; i++) cout<<array[i]<<","; cout<<endl; return 0; } void quicksort(int a[], int left, int right) // 快排演算法 { if(left<right) { int pivotpos = partition(a,left,right); // 排好序的基準元素 quicksort(a,left, pivotpos-1); // 根據基準元素劃分的塊,遞迴 quicksort(a,pivotpos+1,right); // 根據基準元素劃分的塊,遞迴 } } int partition(int a[], int left, int right) // 劃分演算法,核心 { int pivot = a[left]; while(left<right) // 兩個相遇結束 { while(left<right && a[right] >= pivot) --right; //從每一部分的最後一位開始檢查 if(left<right) a[left++] = a[right]; // 將比基準小的放在基準左側 while(left<right && a[left] <= pivot) ++left; // 從每一部分的最初一位開始檢查 if(left<right) a[right--] = a[left];// 將比基準大的放在基準右側 } a[left] = pivot; // 將基準元素放在最終的位置上,使得左邊都是比他小的,右邊都是比他大的 return left; }