排序算法-----归并排序
归并算法的思想就是 分而治之。将序列不换分成不同的序列,分别进行序列化然后归并所有的序列。
具体步骤:
- 把长度为n的输入序列分成两个长度为n/2的子序列;
- 对这两个子序列分别采用归并排序;
- 将两个排序好的子序列合并成一个最终的排序序列。
对数组{3,55,10,2,66,30,6,19,25,9};序列最左端下标为L 中间M 右端R;
不断进行序列的划分,直到L>R,然后进行序列的归并。
采用递归方法
代码如下:
//并轨函数
void Merge(int *dst, int *src, int left, int m, int right)
{
int i = left, j = m + 1;
int k = left;
while (i <= m && j <= right)
{
dst[k++] = src[i] < src[j] ? src[i++] : src[j++];
}
while (i <= m)
{
dst[k++] = src[i++];
}
while (j <= right)
{
dst[k++] = src[j++];
}
}
//并轨排序(递归)
void MergePass(int *br, int *ar, int left, int right)
{// 2 2
if (left < right)
{
int mid = (right - left + 1) / 2 + left - 1;//
MergePass(br, ar, left, mid);
MergePass(br, ar, mid + 1, right);
Merge(br, ar, left, mid, right);
cout << left << " " << mid << " " << right << endl;
Copy_Ar(ar, br, left, right);//自己写的简单的数组拷贝
}
}
void MergeSort(int *ar, int num)//(数组, 长度)
{
int * br = (int*)malloc(sizeof(int)*num);
MergePass(br, ar, 0, num - 1);
free(br);
}
打印结果:
原始数据:3 55 10 2 66 30 6 19 25 9
0 0 1
3 55 10 2 66 30 6 19 25 9
3 3 4
3 55 10 2 66 30 6 19 25 9
2 2 4
3 55 2 10 66 30 6 19 25 9
0 1 4
2 3 10 55 66 30 6 19 25 9
5 5 6
2 3 10 55 66 6 30 19 25 9
8 8 9
2 3 10 55 66 6 30 19 9 25
7 7 9
2 3 10 55 66 6 30 9 19 25
5 6 9
2 3 10 55 66 6 9 19 25 30
0 4 9
2 3 6 9 10 19 25 30 55 66
并轨过程,就是两个序列排序的过程,这两个序列是(L,M)和(M+1, R)在比较的过程中,将比较结果保存在一个数组dst中,无论是(L,M)或者(M+1, R)哪个序列先遍历结束,然后将剩余部分直接保存在数组dst中即可。然后再将dst中的元素拷贝到原始序列(L,M)中。
非递归
//并轨排序(非递归)
void MergePass(int *dst, int *src, int s, int n)
{
int i;
for (i = 0; i + 2 * s - 1 <= n - 1; i += (2 * s))
{
//并轨函数与递归方法并轨函数相同
Merge(dst, src, i, i + s - 1, i + 2 * s - 1);
}
if (n - 1 >= i + s)
{
Merge(dst, src, i, i + s - 1, n - 1);
}
else
{//没有办法参与的数据进行拷贝回去。
for (int j = i; j < n; j++)
{
dst[j] = src[j];
}
}
}
void MergeSort(int *ar, int num)
{
int s = 1;
int n = num;
int *br = (int*)malloc(sizeof(int)*n);
while (s < n)
{
MergePass(br, ar, s, n);
s += s;
MergePass(ar, br, s, n);
s += s;
}
free(br);
}