上兩篇部落格使用的選擇排序和插入排序的演算法複雜度都是o(n2),這在陣列元素比較多的時候和一些演算法複雜度為o(nlogn)的快速排序演算法相比,差距還是很明顯的,如下圖
當有10萬個元素的時候,快速排序演算法比普通的選擇排序演算法要快了6000倍,
本篇部落格介紹的是快速排序演算法中的歸併排序
歸併排序是利用歸併的思想實現的排序方法,該演算法採用經典的分治策略(分治法將問題分成一些小的問題然後遞迴求解,而治的階段則將分的階段得到的各答案"修補"在一起,即分而治之)。
可以看到這種結構很像一棵完全二叉樹,本文的歸併排序採用遞迴去實現,遞迴深度為logn。
分階段就是將陣列不斷進行對半切分,直到最後每部分只剩下乙個元素為止,此時只有乙個元素我們就認為該部分是有序的。
治階段,我們需要將兩個已經有序的子串行合併成乙個有序序列,比如上圖中的最後一次合併,要將[4,5,7,8]和[1,2,3,6]兩個已經有序的子串行,合併為最終序列[1,2,3,4,5,6,7,8],來看下實現步驟。
合併階段需要在空間裡另外開闢乙個和陣列相同大小的空間來存放排好序的陣列,為上圖的temp
定義指向temp的索引為k,指向左邊序列的索引為i,指向右邊序列的索引為j,左邊序列最後乙個元素的索引為mid
採用遞迴方法實現歸併排序:
#include
#ifndef _sortinghelp_h_
#define _sortinghelp_h_
#include
"sortinghelp.h"
#endif
// _sortinghelp_h_
using namespace std;
//將arr[l...mid]和arr[mid+1...r]兩部分進行歸併
template
void
__merge
(t arr,
int l,
int mid,
int r)
int i = l, j = mid +1;
for(
int k = l; k <= r; k++
)else
if(j > r)
else
if(aux[i-l]
< aux[j-l]
)else}}
//遞迴使用歸併排序,對arr[l...r]的範圍進行排序
template
void
__mergesorting
(t arr,
int l,
int r)
template
void
mergesorting
(t arr,
int n)
intmain()
sortinghelp.h定義為
#include
#include
//time()函式
#include
//rand()函式
#include
//assert()函式
using namespace std;
int*
generaterandomarray
(int n,
int rangel,
int ranger)
return arr;
}int
*generatenearlyorderedarray
(int n,
int swaptimes)
srand
(time
(null))
;for
(int i =
0; i < swaptimes; i++
)return arr;
}template
void
printarray
(t arr,
int n)
cout<
//換行
return;}
template
bool issorted
(t arr,
int n)
return true;
}template
void
testsorting
(string sortname,
void
(*sorting)
(t,int
), t arr,
int n)
int*
copyintarray
(int arr,
int n)
template
//定義模板型別,使對各種資料型別都適用,如double,float,string
void
selectionsorting
(t a,
int n)
swap
(a[i]
, a[minindex]);
}}template
void
insertionsortingimproved
(t arr,
int n)
else
} arr[j]
= temp;
}return
;}
執行時間為:
可以看出歸併排序比普通的插入排序確實快了很多倍
對於近乎有序的陣列來說,執行下面的測試程式
int
main()
執行時間為
可以看出對於近乎有序的陣列來說,插入排序的效果還是很好的,要優於歸併排序
資料結構與演算法之歸併排序
歸併排序 merge sort 是建立在歸併操作上的一種有效的排序演算法,該演算法是採用分治法 divide and conquer 的乙個非常典型的應用。將已有序的子串行合併,得到完全有序的序列 即先使每個子串行有序,再使子串行段間有序。若將兩個有序表合併成乙個有序表,稱為二路歸併。歸併過程為 比...
《資料結構與演算法》之排序演算法(歸併排序)
5 歸併排序 歸併排序 merge sort 是建立在歸併操作上的一種有效的排序演算法,該演算法是採用分治法 divide and conquer 的乙個非常典型的應用。將已有序的子串行合併,得到完全有序的序列 即先使每個子串行有序,再使子串行段間有序。若將兩個有序表合併成乙個有序表,稱為二路歸併。...
資料結構 排序演算法之歸併排序
基本思想 將待排序的元素序列分成兩個等長的子串行,再將子串行劃分子串行,直到子串行中只有乙個元素就不用在對子序列繼續進行劃分,將劃分的每個區塊,進行排序,然後再將其歸併到乙個序列中,直到將所有的子串行歸併完成之後,則這個序列就完成了排序。1 基本思想如下所示 經過上面的劃分,從而可以看出經過劃分與歸...