前言
归并排序的核心其实算是合并两个有序的数组,我之前一直是用的判空实现的,即判断两个数组谁先空并且把另外一个剩下的接上去,但是这样在处理边界和结束条件的时候总感觉有些困难,然后昨天在算法导论上看到了使用哨兵来进行合并操作,觉得思路很棒,就来实现一下了。
代码
#include<iostream>
#include<vector>
using namespace std;
void myMerge(int a[], int p, int q, int r) { //p ~ q, q+1 ~ r
int n1 = q - p + 1; //数组1的长度
int n2 = r - q; //数组2的长度
vector<int> L(n1 + 1);
vector<int>R(n2 + 1);
for (int i = 0; i < n1; i++)
L[i] = a[p + i];
for (int i = 0; i < n2; i++)
R[i] = a[q + 1 + i];
L[n1] = 99999; //假装这是无穷大的哨兵
R[n2] = 99999;
int i = 0, j = 0;
for (int k = 0; k < r - p + 1; k++) { //注意这里的终止条件,因为只有r - p + 1个元素,所以只要移动这么多次即可判定合并完成
if (L[i] > R[j]) {
a[p + k] = R[j];
j++;
}
else {
a[p + k] = L[i];
i++;
}
}
}
void mergeSort(int a[], int low, int high) { //归并排序的递归题,很容易实现
if (low == high)
return;
else{
int mid = (low + high) / 2;
mergeSort(a, low, mid);
mergeSort(a, mid + 1, high);
myMerge(a, low, mid, high);
return;
}
}
int main() {
int a[] = { 3, 2, 4, 1, 7, 5, 6 };
int b[] = { 1, 3, 5, 6, 2, 4, 7 };
myMerge(b, 0, 3, 6); //检验合并函数
for (int i = 0; i < 7; i++)
cout << b[i] <<" ";
cout << endl;
mergeSort(a, 0, 6); //检验归并排序函数
for (int i = 0; i < 7; i++)
cout << a[i] << " ";
cout << endl;
return 0;
}