ACM基礎(四) 排序之歸併排序

2021-10-03 05:58:11 字數 2648 閱讀 8584

二、特點

三、實現

**排序演算法(四)之歸併排序

【分治思想理解:錯在以為最小問題是會直接比較兩個元素,真正的做法是解部分乾脆就不比較,直接劃分成單個元素,由並部分比較兩個元素及其以上】的確,歸併排序的解部分的功能和並部分的功能重複,可以寫到一起。

錯誤理解:

正確理解:

// 偽**

// 陣列a,開始下標p,結束下標r

merge-

sort

(a, p, r)

// 保證pif p// 分成兩半排序

// 選取q,奇數個數就是中間的值的下標,偶數個數就是中間偏左的值的下標

then q ← ⌊(p + r)/2

)⌋ // 從p到q

merge-

sort

(a, p, q)

// 從q+1,到r。q已經在它該在的位置上了。

merge-

sort

(a, q +

1, r)

// 歸併部分

merge

(a, p, q, r)

// 陣列a,開始下標p,中間位置的下標q,結束下標r

merge

(a, p, q, r)

// 從p到q(包括)共有多少個元素

n1 ← q - p +

1// 從q+1到r(包括)共有多少個元素

n2 ← r - q

// 建立兩個陣列l和r,元素個數是n+1個

create arrays l[

1..n1+1]

and r[

1..n2+1]

// l陣列是a陣列的從p到q(包括)部分

for i ← 1 to n1

do l[i] ← a[p + i -1]

// r陣列是a陣列的從q+1到r(包括)部分

for j ← 1 to n2

do r[j] ← a[q + j]

// 正無窮,用於當l、r陣列遍歷結束時,l[i]、r[j]就是正無窮。

l[n1 +

1] ← ∞

r[n2 +

1] ← ∞

// 將l和r陣列中的元素按照特定的方式插入到a陣列中。

// l陣列的下標,指在l陣列最左邊(即a陣列的p)

i ← 1

// r陣列的下標,指在r陣列最左邊(即a陣列的q+1)

j ← 1

// 遍歷a陣列中的p到r部分。

for k ← p to r

// 將l[i]和r[j]中較小的元素插入到a中

// 如果l[i]小於等於r[j]。這個等於在這裡,保證了同值的元素保持原來的先後順序

doif l[i] ≤ r[j]

// 將更小的元素l[i]插入到a陣列中,l陣列的下標i右移

then a[k] ← l[i]

i ← i +

1// 如果r[i]比l[j]更小

// 將更小的元素r[i]插入到a陣列中,r陣列的下標j右移

else a[k] ← r[j]

j ← j+

1

優點:

缺點:時間複雜度:

#include

using

namespace std;

// acm中的無窮大常量

#define inf 0x3f3f3f3f

void

merge

(int a,

int p,

int q,

int r)

// r陣列是a陣列的從q+1到r(包括)部分

for(

int j =

0; j < n2; j++

)// 正無窮,用於當l、r陣列遍歷結束時,l[i]、r[j]就是正無窮。

l[n1]

= inf;

r[n2]

= inf;

// 將l和r陣列中的元素按照特定的方式插入到a陣列中。

// i是l陣列的下標,指在l陣列最左邊(即a陣列的p)

// j是r陣列的下標,指在r陣列最左邊(即a陣列的q+1)

// 遍歷a陣列中的p到r部分。

for(

int i =

0, j =

0, k = p; k <= r; k++

)// 如果r[i]比l[j]更小

// 將更小的元素r[i]插入到a陣列中,r陣列的下標j右移

else

}// 釋放陣列

delete

l,r;

}// 下標從p到q(包括q)

void

merge_sort

(int a,

int p,

int r)

}int

main()

;int length =

sizeof

(a)/

sizeof

(int);

merge_sort

(a,0

, length -1)

;for

(int i =

0; i < length; i++

)return0;

}

ACM基礎(四) 排序之快速排序

二 c 實現 快速排序,也是分治法。意義 就是通過pivot將陣列分成兩部分,前面的一部分小於等於pivot,後面的一部分大於pivot。將倒數第一作為 軸 pivot 建立兩個哨i 開始再往前乙個 i 1表示大於pivot的元素 j 遍歷的 從開始到倒數第二 表示當前小於等於pivot的元素 遍歷...

19 排序 歸併排序

將已有序的子串行合併,得到有完全有序的序列 leftstart 左邊陣列的起始位置,rightstart 右邊陣列的起始位置,rightend 右邊陣列的結束位置 void merge elementtype a,elementtype tmpa,int leftstart,int rightsta...

04 排序 歸併排序

基本原理 對於給定的一組資料 假設有n個資料 首先將每兩個相鄰長度為1的子串行進行歸併,得到n 2個長度為2或者1的有序子串行,再將其兩兩合併,反覆此過程,得到乙個有序序列。package com.sort 歸併演算法 public class testmergesort else while i ...