分治法——即分而治之,把一个大的问题分解为规模较小的,类似于原问题的子问题,然后分别求解子问题,最后合并所有子问题的解建立原问题的解; 即
分——将问题分解为规模更小的子问题;
治——将这些规模更小的子问题逐个击破;
合——将已解决的子问题合并,最终得出“母”问题的解;
归并序的分治思想
分解——将待排序的个元素的序列分解为两个各具n/2个元素的子序列;
解决——使用归并排序递归的分别排序两个子序列
合并——将两个已排序的子序列合并为一个有序序列,即产生原代排序序列的有序序列
上面是算法导论中对于归并排序的解释,伪码展示如下,便于理解实现代码
Mergesort( A[n], length )
if(n!=1)
Mergesort(L[n/2],length/2);
Mergesort(R[n/2],length/2);
Merge (R[n/2]),L[n/2],A[n]) //Merge (A[],B[],C[])函数为将有序数组A,B合并为一个数组C;
实现如下,还原伪码的形式,以体现分治的思想
//归并排序——递归实现
#include "stdafx.h"
#include <iostream>
using namespace std;
# define MAX 64//待排序列的元素最大个数
//合并函数,将两个有序数组合并到一个数组中,合并后仍有序(从小到大)
int *merge(int *L0, int llength0, int * R0, int rlength0, int* array0)
{
int k = 0;
int i = 0;
int j = 0;
while ((i < llength0) && (j < rlength0))
{
if (L0[i] < R0[j])array0[k++] = L0[i++];
else array0[k++] = R0[j++];
}
while (i < llength0) { array0[k++] = L0[i++]; }
while (j < rlength0) { array0[k++] = R0[j++]; }
return array0;
}
//归并排序
#if 1
int * mergesort(int*ary0, int length)
{
if (length <= 1) return ary0; //递归的终止条件
int llength;
int rlength;
int* L=new int[length / 2];
int *R=new int[length-length/2];
for (llength = 0; llength < length / 2; llength++)
{
L[llength] = ary0[llength];
}
for (rlength = 0; length / 2 + rlength < length; rlength++)
{
R[rlength] = ary0[rlength + length / 2];
}
mergesort(L, llength);
mergesort(R, rlength);
merge(L, llength, R, rlength, ary0);
delete[] R;
delete[] L;
return ary0;
}
#endif
//输出测试
int main()
{
int number = 0;
cout << "please input the numbre of the element:\n ";
loop:cin >> number;
if (number>MAX||number<1)
{
cout << "error!please input the right number:\n";
goto loop;
}
int *b = new int[number];
cout << "please input the unsorteded sequence:\n";
for (int i = 0; i < number; cin >> b[i], i++);//将待排序序列存储到数组中
mergesort(b, number);
for (int j = 0; j < number; j++) //顺序输出已排好序的数组
{
if (j != number - 1)
cout << b[j] << "<";
else cout << b[j];
}
cout << cnt;
return 0;
}