ACM实习之分治与递归

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

void MergeSort(Type a[],int left,int right)

②template

void merge(Type a[],Type b[],int left,int mid,int right)

③template

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
void MergeSort(Type a[],int left,int right)

{

Type *b=new Type[];

if(left至少有两个元素

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

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的范围[leftmid],j的范围[mid+1,right]

{

if(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

void copy(Type a[],Type b[],int left,int right)

{

int i;

for(i=left;i<=right;i++)

a[i]=b[i];

}

 

 

具体代码:

#include

using namespace std;

template

void MergeSort(Type a[],int left,int right)

{

Type *b=new Type[];

if(left至少有两个元素

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

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的范围[leftmid],j的范围[mid+1,right]

{

if(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

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<

cout<<"}"<

}

5.调试分析
#include

using namespace std;

template

void MergeSort(Type a[],int left,int right)

{

Type *b=new Type[];

if(left至少有两个元素

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

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的范围[leftmid],j的范围[mid+1,right]

{

if(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

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<

cout<<"}"<时间复杂度T(n)=O(1),空间复杂度S(n)=O(1)

}

6.使用说明

程序名为1.exe,运行环境为VC++6.0。程序执行后显示

 

7.测试结果

1建立程序

输出:{1,2,3,4,5,6,7,8,}

 

你可能感兴趣的:(ACM实习之分治与递归)