歸併排序:顧名思義,就是不斷的將兩個有序的子串行歸併成乙個大的序列。所以核心操作就是有序子列的歸併,如果有兩個子列,共有n個元素,那麼歸併的時間複雜度是t(n)=o(n)。有了歸併演算法,我們採用易於理解的方式,分而治之的思想,也就是不斷地遞迴將大的序列劃分成小的序列,當序列只有乙個元素的時候(自身有序),就是遞迴終止條件。
//歸併排序-遞迴實現
//o(nlogn) o(n)
#includeusing namespace std;
void merge(vector& arr,vector& aux,int l,int r,int rightend)
while (l <= leftend)
aux[i++] = arr[l++]; //直接複製左邊剩下的
while (r <= rightend)
aux[i++] = arr[r++]; //直接複製右邊剩下的
for (i = 0; i < count; i++,rightend--) //將有序序列aux複製回arr
arr[rightend] = aux[rightend];
}void msort(vector& arr,vector& aux,int l,int rightend)
int main() ;
mergesort(arr);
for (auto x : arr)
cout << endl;
system("pause");
return 0;
}
1 2 3 4 5 6 7 8 9 10
請按任意鍵繼續. . .
效能分析:分而治之,t(n)=t(n/2)+t(n/2)+o(n) → t(n)=o(n logn);merge過程嚴格保證序列1小於等於序列2,使之穩定。
歸併排序非遞迴演算法:比遞迴演算法更快速,也是穩定的
//歸併排序-迴圈實現
//o(nlogn) o(n)
#includeusing namespace std;
void merge(vector& arr,vector& aux,int l,int r,int rightend)
while (l <= leftend)
aux[i++] = arr[l++]; //直接複製左邊剩下的
while (r <= rightend)
aux[i++] = arr[r++]; //直接複製右邊剩下的
//for (i = 0; i < count; i++,rightend--) //將有序序列aux複製回arr
// arr[rightend] = aux[rightend]; //因為兩次mergepass操作使得無需這一步
}void mergepass(vector& arr,vector& aux,int n,int length)
if (i + length < n) //歸併最後2個子列
merge(arr, aux, i, i + length, n - 1);
else //最後只剩乙個
for (j = i; j < n; j++) aux[j] = arr[j];
}void mergesort(vector& arr)
}int main() ;
mergesort(arr);
for (auto x : arr)
cout << endl;
system("pause");
return 0;
}
1 2 3 4 5 6 7 8 9 10
請按任意鍵繼續. . .
常用演算法排序(04) 歸併排序
歸併排序是利用先遞迴進行分解,將乙個規模為 n nn 的問題分解成兩個規模為 n 2 n 2n 2 的問題,再不斷的繼續進行遞迴分解成最終規模為1 11的問題。然後再逐漸的從小規模結果進行合併,最終得到完整的結果。也即分而治之的思想。其 如下 原圖位址 歸併排序使用了空間換時間的方式,用乙個輔助陣列...
04 排序 歸併排序
基本原理 對於給定的一組資料 假設有n個資料 首先將每兩個相鄰長度為1的子串行進行歸併,得到n 2個長度為2或者1的有序子串行,再將其兩兩合併,反覆此過程,得到乙個有序序列。package com.sort 歸併演算法 public class testmergesort else while i ...
歸併排序(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非遞...