二路歸併排序
阿新 • • 發佈:2020-10-13
思路總結
- 先將n個記錄兩兩分組
- 若n為奇數也沒關係,1個記錄的組不需要進行比較,回到遞迴上一層會進行3個記錄的merge
- 分組完成後,進行兩兩合併merge,merge中進行排序
- 因為兩個需要合併的陣列都是有序的,所以不需要O(nlogn)的排序方法,進行O(n)的比較排序即可
- merge中需要輔助陣列,儲存排序過程
注意
- 時間複雜度O(nlogn),n個記錄,需要logn趟twoWayMerge,每趟中的merge需要n-1次比較
- 空間複雜度O(n)
- 穩定演算法
程式碼
#include <iostream> #include <vector> using namespace std; void merge(vector<int>& v, int l, int mid, int r) { vector<int> temp(r - l + 1); int i = l, j = mid + 1, tempIndex=0; while (i <= mid && j <= r) { if (v[i] <= v[j]) temp[tempIndex++] = v[i++]; else temp[tempIndex++] = v[j++]; } while (i <= mid) temp[tempIndex++] = v[i++]; while (j <= r) temp[tempIndex++] = v[j++]; for (i = l, tempIndex=0; i <= r; i++,tempIndex++) { v[i] = temp[tempIndex]; } } void twoWayMerge(vector<int>& v, int l, int r) { if (l == r) return; else { int mid = (l + r) >> 1; twoWayMerge(v, l, mid); twoWayMerge(v, mid + 1, r); merge(v, l, mid, r); } } int main() { vector<int> v = { 49,38,65,97,76,13,27,49 }; twoWayMerge(v,0,v.size()-1); for (auto a : v) cout << a << " "; cout << endl; return 0; }