二路归并排序(递归,c++)
思想:二路归并排序利用分治的思想,化繁为简,将数组分成一个个的元素,而后两两合并成新的数组片段,最后再将数组片段两两合并,直到合并成一个数组为止。
附上代码:
主要有两个函数,merge是将两个数组片段(即datas[low]到datas[mid],datas[mid + 1] 到datas[high])合并起来,buffers数组暂存数据。比较容易理解。
void merge(int datas[], int buffers[], int low, int mid, int high)
{
int i = low;
int j = mid + 1;
int k = low;
while (i <= mid && j <= high)
{
if (datas[i] < datas[j])
{
buffers[k++] = datas[i];
i++;
}
else
{
buffers[k++] = datas[j];
j++;
}
}
while (i <= mid)
{
buffers[k++] = datas[i];
i++;
}
while (j <= high)
{
buffers[k++] = datas[j];
j++;
}
}
之后还有一个mergeSort函数,这个函数主要用来递归处理数据。记得最后要把buffers的数据回写到datas里,因为合并的时候要用的是两个有序的数组片段。附上代码:
void mergeSort(int datas[], int buffers[], int low, int high)
{
if (low < high)
{
int mid = (low + high) / 2;
mergeSort(datas, buffers, low, mid);
mergeSort(datas, buffers, mid + 1, high);
merge(datas, buffers, low, mid, high);
for (int i = low; i <= high; i++)
{
datas[i] = buffers[i];
}
}
}
完整代码:
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
#pragma warning(disable:4996);
void merge(int datas[], int buffers[], int low, int mid, int high)
{
int i = low;
int j = mid + 1;
int k = low;
while (i <= mid && j <= high)
{
if (datas[i] < datas[j])
{
buffers[k++] = datas[i];
i++;
}
else
{
buffers[k++] = datas[j];
j++;
}
}
while (i <= mid)
{
buffers[k++] = datas[i];
i++;
}
while (j <= high)
{
buffers[k++] = datas[j];
j++;
}
}
void mergeSort(int datas[], int buffers[], int low, int high)
{
if (low < high)
{
int mid = (low + high) / 2;
mergeSort(datas, buffers, low, mid);
mergeSort(datas, buffers, mid + 1, high);
merge(datas, buffers, low, mid, high);
for (int i = low; i <= high; i++)
{
datas[i] = buffers[i];
}
}
}
int main() {
int a[7] = { 49, 38, 65, 97, 76, 13, 27 };
int b[7];
mergeSort(a, b, 0, 6);
for (auto i : a)
{
cout << i << endl;
}
return 0;
}
时间复杂度分析:
当有n个需要排序的数时,执行log2N次归并,每次归并执行不超过n次比较,所以时间复杂度为nlog2N。
稳定性:
归并排序是稳定排序。看第一张图就知道,他不会打乱相等元素的顺序。