算法设计与分析:递归与分治法-实验报告
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
应用数学学院信息安全专业班学号姓名
实验题目递归与分治法
综合实验评分表
实验报告
一、实验目的与要求
1.掌握递归算法的设计思想
2.掌握分治法设计算法的一般过程
3.理解并掌握算法渐近时间复杂度的分析方法
二、实验内容
1、折半查找的递归算法
(1)源程序代码
#include <StdAfx.h>
#include <iostream>
using namespace std;
int bin_search(int key[],int low, int high,int k)
{
int mid;
if(low>high)
return -1;
else{
mid = (low+high) / 2;
if(key[mid]==k)
return mid;
if(k>key[mid])
return bin_search(key,mid+1,high,k);
else
return bin_search(key,low,mid-1,k);
}
}
int main()
{
int n , i , addr;
int A[10] = {2,3,5,7,8,10,12,15,19,21};
cout << "在下面的10个整数中进行查找" << endl;
for(i=0;i<10;i++){
cout << A[i] << " " ;
}
cout << endl << endl << "请输入一个要查找的整数" << endl;
cin >> n;
addr = bin_search(A,0,9,n);
if(-1 != addr)
cout << endl << n << "是上述整数中的第" << addr << "个数" << endl;
else
cout << endl << n << "不在上述的整数中" << endl << endl;
getchar();
return 0;
}
(2)运行界面
①查找成功
②查找失败
2、用分治法求x的n次方,要求时间复杂度为O(lgn)
(1)源程序代码
#include <StdAfx.h>
#include <iostream>
using namespace std;
int Pow(int x, int n)
{
if (n == 1)
return x;
else if (n > 1)
{
int s;
int m = n / 2;
s = Pow (x, m);
if (n % 2 == 0)
return (s * s);
else
return (s * s * x);
}
}
int main()
{
int x, n;
cout << "你将进行x的n次方计算" << endl << endl;
cout << "请输入x:" << endl;
cin >> x;
cout << "请输入n:" << endl;
cin >> n;
cout << endl << "计算结果:" << Pow(x, n) << endl << endl;
return 0;
}
(2)运行界面
3、自然合并排序算法
(1)源程序代码
#include "StdAfx.h"
#include <iostream>
using namespace std;
const int SIZE = 100;
int arr[SIZE];
int rec[SIZE];
void merge(int fir,int end,int mid);
int pass(int n);
void mergeSort(int n);
void mergeSort(int n){
int num=pass(n);
while(num!=2){
for(int i=0;i<num;i+=2)
merge(rec[i],rec[i+2]-1,rec[i+1]-1);
num=pass(n);
}
}
void merge(int fir,int end,int mid){
int tempArr[SIZE];
int fir1=fir,fir2=mid+1;
for(int i=fir;i<=end;i++){
if(fir1>mid)
tempArr[i]=arr[fir2++];
else if(fir2>end)
tempArr[i]=arr[fir1++];
else if(arr[fir1]>arr[fir2])
tempArr[i]=arr[fir2++];
else
tempArr[i]=arr[fir1++];
}
for(int i=fir;i<=end;i++)
arr[i]=tempArr[i];
}
int pass(int n){
int num=0;
int biger=arr[0];
rec[num++]=0;
for(int i=1;i<n;i++){
if(arr[i]>=biger)biger=arr[i];
else {
rec[num++]=i;
biger=arr[i];
}
}
rec[num++]=n;
return num;
}
int main(){
int n;
cout<<"请输入需要排序的整数个数:"<<endl;
while(cin>>n){
for(int i=0;i<n;i++){
cout<<"请输入整数:"<<endl;
cin>>arr[i];
}
mergeSort(n);
cout<<"排序结果为:"<<endl;
for(int i=0;i<n;i++){
cout<<arr[i]<<" ";
}
cout<<endl<<endl;
cout<<"请输入需要排序的整数个数:"<<endl;
}
return 0;
}
(2)运行界面
三、问题与讨论
问题:分治法能解决的问题一般具有什么特征?
解答:任何一个可以用计算机求解的问题所需的计算时间都与其规模有关。
问题的规模越小越容易直接求解,解题所需的计算时间也越少。
分治法的设计思想是,将一个难以直接解决的大问题,分割成一些规模较小的相同问题,以便各个击破,分而治之。
分治法所能解决的问题一般具有以下几个特征:
(1)该问题的规模缩小到一定的程度就可以容易地解决;
(2)该问题可以分解为若干个规模较小的相同问题,即该问题具有最优子结构性质;
(3)利用该问题分解出的子问题的解可以合并为该问题的解;
(4)该问题所分解出的各个子问题是相互独立的,即子问题之间不包含公共的子问题。
四、总结
这次实验的内容都很有代表性,通过上机操作实践与对问题的思考,让我更深层地领悟到了分治法的效率。
分治法的基本思路并不难理解,就是将一个难以直接解决的大问题,分割成一些规模较小的相同问题,在计算机的处理当中,问题的规模越小就越容易直接求解,解题所需的计算时间也越少,所以分治法在合适的问题中是能大大提高效率的。
我非常喜欢上机课,因为课上听的理论内容也许觉得懂了,但课后没有一些实践,于是对一些难点实际上掌握得并不好。
刚看到课题的实验内容,其实基本思路和条理还是会有的,因为会有一定的知识基础,能够想到一些相关的解决思路,但有思路不一定就能够解决问题,真正动手去做的时候才发现会出现更多的实际问题。
解决遇到的问题就是我们学习的过程,同时也能让我注意到一些以前不曾在意的问题。
像我是使用C++来写代码的,其中我这次实验时我就发现,“#include “StdAfx.h””一定要放在首行,不然就会出错;调试程序时如果出现“Cannot find or open the PDB file”的提示而导致程序不能正常运行时,按Ctrl+F5来直接执行就能正常运行了,因为这跟系统环境有关系;等等。
每次的实践都能有一些发现,不管是大是小,积累多了就成了自己丰富的经验。
所以我还是挺喜欢实验课的,能进行一些实用性很强的实践,更深层地领悟到书本的理论知识,同时还能享受把bug逐个解决的快感。