快速排序(quick sort)
阿新 • • 發佈:2019-01-05
前面兩個小節,我們分別介紹了氣泡排序,插入排序,在我們本節講解一種更加高效的排序方法,快速排序,也即是常說的快排。
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;
}