該方法的基本思想是:
1.先從數列中取出乙個數作為基準數。
2.分割槽過程,將比這個數大的數全放到它的右邊,小於或等於它的數全放到它的左邊。
3.再對左右區間重複第二步,直到各區間只有乙個數。
以乙個陣列作為示例,取區間第乙個數為基準數。 0
1 23 4
5 67 8
9 72
6 57
88 60
42 83
73 48
85
初始時,i = 0; j = 9; x = a[i] = 72
由於已經將a[0]中的數儲存到x中,可以理解成在陣列a[0]上挖了個坑,可以將其它資料填充到這來。
從j開始向前找乙個比x小或等於x的數。當j=8,符合條件,將a[8]挖出再填到上乙個坑a[0]中。a[0]=a[8]; i++; 這樣乙個坑a[0]就被搞定了,但又形成了乙個新坑a[8],這怎麼辦了?簡單,再找數字來填a[8]這個坑。這次從i開始向後找乙個大於x的數,當i=3,符合條件,將a[3]挖出再填到上乙個坑中a[8]=a[3]; j--;
陣列變為: 0
1 23 4
5 67 8
9 48
6 57
88 60
42 83
73 88
85
i = 3; j = 7; x=72
再重複上面的步驟,先從後向前找,再從前向後找。
從j開始向前找,當j=5,符合條件,將a[5]挖出填到上乙個坑中,a[3] = a[5]; i++;
從i開始向後找,當i=5時,由於i==j退出。
此時,i = j = 5,而a[5]剛好又是上次挖的坑,因此將x填入a[5]。
快速排序函式段如圖所示,
int quicksort(vector &v, int left, int right)這樣通過先遞迴的分解數列,再合併數列就完成了歸併排序。v[low] = v[high];
while(low < high && v[low] < key)
v[high] = v[low];
}v[low] = key;
quicksort(v,left,low-1);
quicksort(v,low+1,right);
}}
[cpp]view plain
copy
//將有二個有序數列a[first...mid]和a[mid...last]合併。
void
mergearray(
inta,
intfirst,
intmid,
intlast,
inttemp)
while
(i <= m)
temp[k++] = a[i++];
while
(j <= n)
temp[k++] = a[j++];
for(i = 0; i < k; i++)
a[first + i] = temp[i];
} void
mergesort(
inta,
intfirst,
intlast,
inttemp)
} bool
mergesort(
inta,
intn)
歸併排序的效率是比較高的,設數列長為n,將數列分開成小數列一共要logn步,每步都是乙個合併有序數列的過程,時間複雜度可以記為o(n),故一共為o(n*logn)。因為歸併排序每次都是在相鄰的資料中進行操作,所以歸併排序在o(n*logn)的幾種排序方法(快速排序,歸併排序,希爾排序,堆排序)也是效率比較高的。
快速排序(遞迴,歸併)
include using namespace std const int n 1e5 int q n n 待排序陣列 int main 1 任意選擇乙個至作為中間值,將比中間值大的放在右邊,小的放在左邊,中間值可以是待排序陣列中的任意乙個數,這裡取q l r 2 2 分別用兩個指標i,j指向陣列的...
遞迴 快速排序與歸併排序
includeint a 101 n 定義全域性變數,將在子函式中呼叫 void quicksort int left,int right 最終將基數歸位 基數歸中 a left a i 將i,j相遇時的那個值作為下次遞迴呼叫的基!每個進行遞迴呼叫可以確定乙個基數字置 將基數擺到正確位置 a i t...
遞迴 快速排序 快速排序
問題描述 用遞迴來實現快速排序 quick sort 演算法。快速排序演算法的基本思路是 假設要對乙個陣列a進行排序,且a 0 x。首先對陣列中的元素進行調整,使x放在正確的位置上。同時,所有比x小的數都位於它的左邊,所有比x大的數都位於它的右邊。然後對於左 右兩段區域,遞迴地呼叫快速排序演算法來進...