思路总结
- 先将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;
}