需要遞迴的排序方式 快速排序歸併排序演算法分析

2021-07-25 07:03:04 字數 1906 閱讀 8453

該方法的基本思想是:

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大的數都位於它的右邊。然後對於左 右兩段區域,遞迴地呼叫快速排序演算法來進...