merge_sort是分治法的乙個典型應用。這裡有一張《各類排序演算法時間、空間複雜度對比表》,從表中可以看得出,merge_sort(歸併排序演算法)是比較穩定的演算法,使用較廣泛。求逆序對也是很好用的。
分治過程概括圖:藍色的原始陣列,運用merge_sort以後為有序的綠色陣列
我的理解:主要想說二路歸併(大佬請忽略)
1. merge() 是二路歸併的階段,簡單來說是有序表的合併。這時有兩段:左段 al~amid 和右段 amid+1~ar ,轉移陣列 c 的下標從 cnt=0 開始,定義左右兩段的下標分別為 i 、j ,且 i 指向 al ,j 指向 amid+1 。現在不停地比較 ai 與 aj 的值大小,總是將較小(以公升序為例,降序稍加修改,就改三四處)的乙個值賦給 c 陣列,如果 ai 較小 ( aj 的話,後面改為 j ),則 i 和 cnt 均 加 1,直到兩段其中有一段的長度為零(下標到結尾)。最後,將長度不為零的一段剩下的a值全部給 c 陣列,merge() 函式完成。在 a 陣列的值給到 c 陣列的過程中,我們總是選最小的。實際上,左段和右段都是有序的(或者如圖一的第一行綠色只有乙個元素),我們每次兩兩比較又總是取較小的加入 c 陣列,所以 c 中的值是嚴格的由小到大。最後從 cnt=0 開始回給到 a 後,新的 a 陣列順序也是嚴格的由小到大。
對應code:
constmerge()int m=1e5+5
;int
a[m];
void merge(int l,int m,int
r)
while(i<=m)
c[cnt++]=a[i++];
while(j<=r)
c[cnt++]=a[j++];
for(int k=0;k)
a[l++]=c[k];
}
2.sort() 內部使用遞迴,遞迴邊界:各有序表長度為 1 ,陣列分兩段進行,然後逐步返回,返回過程呼叫merge()。最終得到有序表a[ ];
對應code:
void mergesort(int l,intmergesort()r)
那麼整個演算法:
1 #include 2 #include 3merge sortusing
namespace
std;45
const
int m=1e5+5;6
inta[m];78
void merge(int l,int m,intr)9
20while(i<=m)
21 c[cnt++]=a[i++];
22while(j<=r)
23 c[cnt++]=a[j++];
24for(int k=0;k)
25 a[l++]=c[k];26}
2728
void mergesort(int l,int
r)29
ps:這裡有兩歸併可解的題:洛谷【p1177】 模板 快速排序 和 洛谷【p1908】逆序對,供測試。
歸併排序(2 路歸併排序)
遞迴寫法 include define maxn 100 void merge int a,int l1,int r1,int l2,int r2 將陣列a的區間 l1,r1 和區間 l2,r2 合併為乙個有序區間 else while i r1 while j r2 for int i 0 i非遞...
python歸併排序 python 歸併排序
排序思路 1.將陣列分成兩組a,b,建立臨時陣列 c,c長度 a b 2.i,j分別屬於a,b 3.若a i b j 將b j 放入c,j 否則 a i 放入c,i 4.迴圈3步驟,將a或b中剩餘的元素放入c,再將c複製到陣列中 5.遞迴3 4直到a,b序列的長度 1 歸併排序 class merg...
排序 歸併排序
歸併 merge 排序法是將兩個 或兩個以上 有序表合併成乙個新的有序表,即把待排序序列分為若干個子串行,每個子串行是有序的。然後再把有序子串行合併為整體有序序列。歸併 將兩個已經排好序的集合合併到乙個集合眾,並且保證新的集合也是有序的。核心點 只有乙個元素的集合是已經排好序的集合。歸併排序是建立在...