1. 分治与递归
编写自然归并合并排序算法
算法描述:对于初始给定的数组,通常存在多个长度大于1的已自然排好序的子数组段.例如,若数组a中元素为{4,8,3,7,1,5,6,2},则自然排好序的子数组段有{4,8},{3,7},{1,5,6},{2}.用一次对数组a的线性扫描就足以找出所有这些排好序的子数组段.然后将相邻的排好序的子数组段两两合并,构成更大的排好序的子数组段({3,4,7,8},{1,2,5,6}).继续合并相邻排好序的子数组段,直至整个数组已排好序。
2.需求分析
本演示程序用VC++6.0编写,完成模板的生成,完成数组的合并排序,最后输出结果。
① 输入的形式和输入值的范围:在主函数初始给定数组,此数组存在多个长度大于1的已自然排好序的子数组段.。
② 输出的形式:通过划分自然排序,线性扫描,.然后将相邻的排好序的子数组段两两合并,构成更大的排好序的子数组段,继续合并相邻排好序的子数组段,直至整个数组已排好序。最后输出已排好序的数组。
③ 程序所能达到的功能:完成数组的合并排序
④ 测试数据:
{4,8,3,7,1,5,6,2}
输出{1,2,3,4,5,6,7,8,}
3.概要设计
1)为了实现上述程序功能,需要定义模板和函数来实现数组的线性扫描,合并相邻排好序的子数组段:
①template<class Type>
void MergeSort(Type a[],int left,int right)
②template<class Type>
void merge(Type a[],Type b[],int left,int mid,int right)
③template<class Type>
void copy(Type a[],Type b[],int left,int right)
1)本程序包含4个函数:
① 主函数main()
② 线性扫描函数MergeSort(Type a[],int left,int right)
③ 排序合并函数merge(Type a[],Type b[],int left,int mid,int right)
④ 复制函数copy(Type a[],Type b[],int left,int right)
各函数间关系如下:
main() MergeSort(Type a[],int left,int right) merge(Type a[],Type b[],int copy(Type a[],Type b[],int left,int right) left,int mid,int right)
4.详细设计
为了实现上述程序功能,需要定义模板和函数来实现数组的线性扫描,合并相邻排好序的子数组段:
① template<class Type>
void MergeSort(Type a[],int left,int right)
{
Type *b=new Type[];
if(left<right){//至少有两个元素
int i=(left+right)/2;//取中点
MergeSort(a,left,i);
MergeSort(a,i+1,right);
merge(a,b,left,i,right);//合并到数组b
copy(a,b,left,right);//复制回数组a
}
}
② template<class Type>
void merge(Type a[],Type b[],int left,int mid,int right)
{
int i=left;
int j=mid+1;
int k=left;
while(i<=mid&&j<=right) //i的范围[left,mid],j的范围[mid+1,right]
{
if(a[i]<a[j])b[k++]=a[i++];
else b[k++]=a[j++];
}
if(i>mid){int m; //左边元素多与右边为真
for(m=j;m<=right;m++)
b[k++]=a[m];}
else {int m;
for(m=i;m<=right;m++)
b[k++]=a[m];}
}
③ template<class Type>
void copy(Type a[],Type b[],int left,int right)
{
int i;
for(i=left;i<=right;i++)
a[i]=b[i];
}
具体代码:
#include<iostream>
using namespace std;
template<class Type>
void MergeSort(Type a[],int left,int right)
{
Type *b=new Type[];
if(left<right){//至少有两个元素
int i=(left+right)/2;//取中点
MergeSort(a,left,i);
MergeSort(a,i+1,right);
merge(a,b,left,i,right);//合并到数组b
copy(a,b,left,right);//复制回数组a
}
}
template<class Type>
void merge(Type a[],Type b[],int left,int mid,int right)
{
int i=left;
int j=mid+1;
int k=left;
while(i<=mid&&j<=right) //i的范围[left,mid],j的范围[mid+1,right]
{
if(a[i]<a[j])b[k++]=a[i++];
else b[k++]=a[j++];
}
if(i>mid){int m; //左边元素多与右边为真
for(m=j;m<=right;m++)
b[k++]=a[m];}
else {int m;
for(m=i;m<=right;m++)
b[k++]=a[m];}
}
template<class Type>
void copy(Type a[],Type b[],int left,int right)
{
int i;
for(i=left;i<=right;i++)
a[i]=b[i];
}
void main()
{
int i;
int c[8]={4,8,3,7,1,5,6,2};
MergeSort(c,0,7);
cout<<"{";
for(i=0;i<=7;i++)
cout<<c[i]<<"," ;
cout<<"}"<<endl;
}
5.调试分析
#include<iostream>
using namespace std;
template<class Type>
void MergeSort(Type a[],int left,int right)
{
Type *b=new Type[];
if(left<right){//至少有两个元素
int i=(left+right)/2;//取中点
MergeSort(a,left,i);
MergeSort(a,i+1,right);
merge(a,b,left,i,right);//合并到数组b
copy(a,b,left,right);//复制回数组a
}
}
template<class Type>
void merge(Type a[],Type b[],int left,int mid,int right)
{
int i=left;
int j=mid+1;
int k=left;
while(i<=mid&&j<=right) //i的范围[left,mid],j的范围[mid+1,right]
{
if(a[i]<a[j])b[k++]=a[i++];
else b[k++]=a[j++];
} //时间复杂度T(n)=O(1),空间复杂度S(n)=O(1)
if(i>mid){int m; //左边元素多与右边为真
for(m=j;m<=right;m++)
b[k++]=a[m];}
else {int m;
for(m=i;m<=right;m++)
b[k++]=a[m];}
} //时间复杂度T(n)=O(1),空间复杂度S(n)=O(1)
template<class Type>
void copy(Type a[],Type b[],int left,int right)
{
int i;
for(i=left;i<=right;i++)
a[i]=b[i];
} //时间复杂度T(n)=O(1),空间复杂度S(n)=O(1)
void main()
{
int i;
int c[8]={4,8,3,7,1,5,6,2};
MergeSort(c,0,7);
cout<<"{";
for(i=0;i<=7;i++)
cout<<c[i]<<"," ;
cout<<"}"<<endl; //时间复杂度T(n)=O(1),空间复杂度S(n)=O(1)
}
6.使用说明
程序名为1.exe,运行环境为VC++6.0。程序执行后显示
7.测试结果
1) 建立程序:
输出:{1,2,3,4,5,6,7,8,}