目录
1.合并排序的概念
合并排序算法是用分治策略实现对n个元素进行排序的算法。其基本思想是:将待排序元素分成大小大致相同的2个子集合,分别对2个子集合进行排序,最终将排好序的子集合合并成为所要求的排好序的集合。合并排序算法可递归地描述如下:
图例:
2.递归实现合并排序
2.1合并函数:
void Merge(int* dest, int* src, int left, int mid, int right)
{
int i = left, j = mid + 1;
int k = left;
while (i <= mid && j <= right)
{
dest[k++] = src[i] < src[j] ? src[i++] : src[j++];
}
while (i <= mid)
{
dest[k++] = src[i++];
}
while (j <= right)
{
dest[k++] = src[j++];
}
}
2.2拷贝函数:
void Copy(int* dest, int* src, int left, int right)
{
for (int i = left; i <= right; i++)
{
dest[i] = src[i];
}
}
2.3划分函数:
void MergePass(int* tmp, int* nums, int left, int right)
{
if (left < right)
{
int mid = (right - left) / 2 + left;
MergePass(tmp, nums, left, mid);
MergePass(tmp, nums, mid + 1, right);
Merge(tmp, nums, left, mid, right);
Copy(nums, tmp, left, right);
}
}
2.4归并排序函数:
void MergeSort(int* nums, int n)
{
if (nums == nullptr || n < 2)return;
int* tmp = new int[n];
MergePass(tmp, nums, 0, n - 1);
delete[]tmp;
}
2.5总代码:
#include<iostream>
using namespace std;
void Merge(int* dest, int* src, int left, int mid, int right)
{
int i = left, j = mid + 1;
int k = left;
while (i <= mid && j <= right)
{
dest[k++] = src[i] < src[j] ? src[i++] : src[j++];
}
while (i <= mid)
{
dest[k++] = src[i++];
}
while (j <= right)
{
dest[k++] = src[j++];
}
}
void Copy(int* dest, int* src, int left, int right)
{
for (int i = left; i <= right; i++)
{
dest[i] = src[i];
}
}
void MergePass(int* tmp, int* nums, int left, int right)
{
if (left < right)
{
int mid = (right - left) / 2 + left;
MergePass(tmp, nums, left, mid);
MergePass(tmp, nums, mid + 1, right);
Merge(tmp, nums, left, mid, right);
Copy(nums, tmp, left, right);
}
}
void MergeSort(int* nums, int n)
{
if (nums == nullptr || n < 2)return;
int* tmp = new int[n];
MergePass(tmp, nums, 0, n - 1);
delete[]tmp;
}
int main()
{
int arr[] = { 56,23,78,45,90,12,34,67,89,100 };
int n = sizeof(arr) / sizeof(arr[0]);
MergeSort(arr, n);
for (int i = 0; i < n; i++)
{
cout << arr[i] << " ";
}
return 0;
}
3.非递归实现合并排序
图示:
#include<iostream>
using namespace std;
void PrintInt(int* arr, int n)
{
for (int i = 0; i < n; i++)
{
cout << arr[i] << " ";
}
cout << endl;
}
void Merge(int* dest, int* src, int left, int mid, int right)
{
int i = left, j = mid + 1;
int k = left;
while (i <= mid && j <= right)
{
dest[k++] = src[i] < src[j] ? src[i++] : src[j++];
}
while (i <= mid)
{
dest[k++] = src[i++];
}
while (j <= right)
{
dest[k++] = src[j++];
}
}
void MergePass(int* dest, int* src, int n, int s)
{
int i = 0;
while (i + 2 * s - 1 <= n - 1)//i<=n-2*s
{
Merge(dest, src, i, i + s - 1, i + 2 * s - 1);
i = i + 2 * s;
}
if (n - 1 >= i + s)
{
Merge(dest, src, i, i + s - 1, n - 1);
}
else
{
for (int j = i; j < n; j++)
{
dest[j] = src[j];
}
}
}
void MergeSort(int* nums, int n)
{
int* tmp = new int[n];
int s = 1;
while (s < n)
{
MergePass(tmp, nums, n, s);
s += s;
MergePass(nums, tmp, n, s);
s += s;
}
delete[]tmp;
}
int main()
{
int arr[] = { 56,23,78,45,90,89,12,34,67,89,100 };
int n = sizeof(arr) / sizeof(arr[0]);
PrintInt(arr, n);
MergeSort(arr, n);
PrintInt(arr, n);
return 0;
}