归并排序
归并也是经典的分治策略, 它将问题分成一些小的问题后递归求解, 而治就是将分段的各个答案合并补在一起
分解 – 将当前区间一分为二,即求分裂点 mid = (low + high)/2;
求解 – 递归地对两个子区间a[low…mid] 和 a[mid+1…high]进行归并排序。递归的终结条件是子区间长度为1。
合并 – 将已排序的两个子区间a[low…mid]和 a[mid+1…high]归并为一个有序的区间a[low…high]。
将数组两半进行比较, 较小的放在新的数组中, 最后将没有放完的一半全部放入新的数组中. 最后将新的数组复制给原数组
void merge(int p[], int Frist, int mid, int Last)
{
int i, j, k;
i = Frist, j = mid + 1, k = 0;
int *a = new int[N];
while (i <= mid && j <= Last)
{
if (p[i] < p[j])
a[k++] = p[i++];
else
a[k++] = p[j++];
}
while (i <= mid)
a[k++] = p[i++];
while (j <= Last)
a[k++] = p[j++];
for (i = 0; i < k; i++)
p[Frist + i] = a[i];
free(a);
}
既然要将数组分半, 那就应该用一个 mid = (first + last) / 2;保存中间的位置, 这样将数组分成前一半和后一半, 直到分成一个一个的数
void merge_groups(int a[], int Frist, int Last)
{
//当数组的 first == last 即分成一个的时候结束分半
if (a == NULL || Frist >= Last)
return;
int mid = (Frist + Last) / 2;
//数组不断地分成两份
merge_groups(a, Frist, mid);
merge_groups(a, mid + 1, Last);
//两个两个数组开始合并
merge(a, Frist, mid, Last);
}
源代码
#include <iostream>
#include <cstdlib>
using namespace std;
void merge(int p[], int Frist, int mid, int Last);
//void merge_sort(int a[], int n);
void merge_groups(int a[], int Frist, int Last);
const int N = 20;
int main()
{
int *p = new int[N];
memset(p, 0, N);
int i = 0, n; cin >> n;
while (i < n)
cin >> p[i++];
//int Frist = 0;
merge_groups(p, 0, n - 1);
for (int i = 0; i < n; i++)
cout << p[i] << " ";
free(p);
system("pause");
return 0;
}
//void merge_sort(int a[], int n)
//{
// if (a == NULL || n <= 0)
// return;
// else
// merge_groups(a, 0, n - 1);
//}
void merge_groups(int a[], int Frist, int Last)
{
//当数组的 first == last 即分成一个的时候结束分半
if (a == NULL || Frist >= Last)
return;
int mid = (Frist + Last) / 2;
//数组不断地分成两份
merge_groups(a, Frist, mid);
merge_groups(a, mid + 1, Last);
//两个两个数组开始合并
merge(a, Frist, mid, Last);
}
void merge(int p[], int Frist, int mid, int Last)
{
int i, j, k;
i = Frist, j = mid + 1, k = 0;
int *a = new int[N];
while (i <= mid && j <= Last)
{
if (p[i] < p[j])
a[k++] = p[i++];
else
a[k++] = p[j++];
}
while (i <= mid)
a[k++] = p[i++];
while (j <= Last)
a[k++] = p[j++];
for (i = 0; i < k; i++)
p[Frist + i] = a[i];
free(a);
}