算法实验一实验报告.docx
- 文档编号:6099773
- 上传时间:2023-01-03
- 格式:DOCX
- 页数:25
- 大小:468.98KB
算法实验一实验报告.docx
《算法实验一实验报告.docx》由会员分享,可在线阅读,更多相关《算法实验一实验报告.docx(25页珍藏版)》请在冰豆网上搜索。
算法实验一实验报告
武汉轻工大学
数学与计算机学院
算法分析实验报告
指导老师:
汤小月
专业:
信息管理与信息系统
班级:
信管1201班
学号:
姓名:
实验一分治与递归(2学时)
基本题一:
基本递归算法
一、实验目的与要求
1、熟悉C/C++语言的集成开发环境;
2、通过本实验加深对递归过程的理解
二、实验内容:
掌握递归算法的概念和基本思想,分析并掌握“整数划分”问题的递归算法。
三、实验题
任意输入一个整数,输出结果能够用递归方法实现整数的划分。
具体程序代码如下:
#include
usingnamespacestd;
intq(intn,intm)//正整数n的最大加数m的划分数
{
if((n<1)||(m<1))return0;//n,m需>1
if((n==1)||(m==1))return1;//正整数或者最大加数=1时,只有一种划分情况
if(n if(n==m)returnq(n,m-1)+1;//递归,n的划分由其q(n,m-1)和n1=n组成 returnq(n,m-1)+q(n-m,m);//正整数n的最大加数n1不大于m的划分由n1=m的划分和n1=m-1的划分组成 } voidmain() { intn,m; cout<<"请输入一个整数n(-1退出): "< cin>>n; while(n>=1) { cout<<"请输入一个最大加数m: "< cin>>m; cout<<"正整数n的最大加数m的划分数为"< cout<<"请输入一个整数n(-1退出): "< cin>>n; } } 进行编译如下: 运行结果如下: 四、实验步骤 1.理解算法思想和问题要求; 2.编程实现题目要求; 3.上机输入和调试自己所编的程序; 4.验证分析实验结果; 5.整理出实验报告。 基本题二: 棋盘覆盖问题 一、实验目的与要求 1、掌握棋盘覆盖问题的算法; 2、初步掌握分治算法 二、实验题: 盘覆盖问题: 在一个2k×2k个方格组成的棋盘中,恰有一个方格与其它方格不同,称该方格为一特殊方格,且称该棋盘为一特殊棋盘。 在棋盘覆盖问题中,要用图示的4种不同形态的L型骨牌覆盖给定的特殊棋盘上除特殊方格以外的所有方格,且任何2个L型骨牌不得重叠覆盖。 三、实验提示 voidchessBoard(inttr,inttc,intdr,intdc,intsize) { if(size==1)return; intt=tile++, //L型骨牌号 s=size/2; //分割棋盘 //覆盖左上角子棋盘 if(dr //特殊方格在此棋盘中 chessBoard(tr,tc,dr,dc,s); else{//此棋盘中无特殊方格 //用t号L型骨牌覆盖右下角 board[tr+s-1][tc+s-1]=t; //覆盖其余方格 chessBoard(tr,tc,tr+s-1,tc+s-1,s);} //覆盖右上角子棋盘 if(dr //特殊方格在此棋盘中 chessBoard(tr,tc+s,dr,dc,s); else{//此棋盘中无特殊方格 //用t号L型骨牌覆盖左下角 board[tr+s-1][tc+s]=t; //覆盖其余方格 chessBoard(tr,tc+s,tr+s-1,tc+s,s);} //覆盖左下角子棋盘 if(dr>=tr+s&&dc //特殊方格在此棋盘中 chessBoard(tr+s,tc,dr,dc,s); else{//用t号L型骨牌覆盖右上角 board[tr+s][tc+s-1]=t; //覆盖其余方格 chessBoard(tr+s,tc,tr+s,tc+s-1,s);} //覆盖右下角子棋盘 if(dr>=tr+s&&dc>=tc+s) //特殊方格在此棋盘中 chessBoard(tr+s,tc+s,dr,dc,s); else{//用t号L型骨牌覆盖左上角 board[tr+s][tc+s]=t; //覆盖其余方格 chessBoard(tr+s,tc+s,tr+s,tc+s,s);} } 编写程序代码如下: #include usingnamespacestd; intboard[65][65],tile;/*tile为纸片编号*/ voidchessBoard(inttr,inttc,intdr,intdc,intsize) { if(size==1)return; intt=tile++,//L型骨牌号 s=size/2;//分割棋盘 //覆盖左上角子棋盘 if(dr //特殊方格在此棋盘中 chessBoard(tr,tc,dr,dc,s); else{//此棋盘中无特殊方格 //用t号L型骨牌覆盖右下角 board[tr+s-1][tc+s-1]=t; //覆盖其余方格 chessBoard(tr,tc,tr+s-1,tc+s-1,s);} //覆盖右上角子棋盘 if(dr //特殊方格在此棋盘中 chessBoard(tr,tc+s,dr,dc,s); else{//此棋盘中无特殊方格 //用t号L型骨牌覆盖左下角 board[tr+s-1][tc+s]=t; //覆盖其余方格 chessBoard(tr,tc+s,tr+s-1,tc+s,s);} //覆盖左下角子棋盘 if(dr>=tr+s&&dc //特殊方格在此棋盘中 chessBoard(tr+s,tc,dr,dc,s); else{//用t号L型骨牌覆盖右上角 board[tr+s][tc+s-1]=t; //覆盖其余方格 chessBoard(tr+s,tc,tr+s,tc+s-1,s);} //覆盖右下角子棋盘 if(dr>=tr+s&&dc>=tc+s) //特殊方格在此棋盘中 chessBoard(tr+s,tc+s,dr,dc,s); else{//用t号L型骨牌覆盖左上角 board[tr+s][tc+s]=t; //覆盖其余方格 chessBoard(tr+s,tc+s,tr+s,tc+s,s);} } //输出最终的结果 voidresult(intb[][65],intn){ inti,j; for(i=1;i<=n;i++) { for(j=1;j<=n;j++) cout< cout< } } intmain(){ intsize,dr,dc; cout<<"选择输入4种不同形态的L型骨牌中的一种(4/8/16/64): "< cin>>size; cout<<"请输入特殊的块的位置(x,y): "< cin>>dr>>dc; cout<<"结果如下: "< board[dr][dc]=-1; tile++; chessBoard(1,1,dr,dc,size); result(board,size); } 运行调试结果如下: 试运行结果如下: 提高题一: 二分搜索 一、实验目的与要求 1、熟悉二分搜索算法; 2、初步掌握分治算法; 二、实验题 1、设a[0: n-1]是一个已排好序的数组。 请改写二分搜索算法,使得当搜索元素x不在数组中时,返回小于x的最大元素的位置I和大于x的最小元素位置j。 当搜索元素在数组中时,I和j相同,均为x在数组中的位置。 2、设有n个不同的整数排好序后存放于t[0: n-1]中,若存在一个下标I,0≤i<n,使得t[i]=i,设计一个有效的算法找到这个下标。 要求算法在最坏的情况下的计算时间为O(logn)。 三、实验提示 1、用I,j做参数,且采用传递引用或指针的形式带回值。 boolBinarySearch(inta[],intn,intx,int&i,int&j) { intleft=0; intright=n-1; while(left { intmid=(left+right)/2; if(x==a[mid]) { i=j=mid; returntrue; } if(x>a[mid]) left=mid+1; else right=mid-1;2 } i=right; j=left; returnfalse; } intSearchTag(inta[],intn,intx) { intleft=0; intright=n-1; while(left { intmid=(left+right)/2; if(x==a[mid])returnmid; if(x>a[mid]) right=mid-1; else left=mid+1; } return-1; } 实验题1代码编写如下: #include usingnamespacestd; voidBubbleSort(int*pData,intCount) //冒泡排序的函数,pData中从0位置处存了Count个数,该函数将数组中元素排序 { intiTemp; for(inti=1;i { for(intj=Count-1;j>=i;j--) { if(pData[j] { iTemp=pData[j-1]; pData[j-1]=pData[j]; pData[j]=iTemp; } } } } boolBinarySearch(inta[],intn,intx,int&i,int&j) //数组a大小为n,数组中存放了已经排好序(升序)的数列 { intleft=0; intright=n-1; intmid=0; while(left { mid=(left+right)/2; if(x==a[mid]) { i=j=mid; returntrue; } if(x>a[mid]) left=mid+1; else right=mid-1; } i=right; j=left; returnfalse; } intSearchTag(inta[],intn,intx) { intleft=0; intright=n-1; while(left { intmid=(left+right)/2; if(x==a[mid]) returnmid; if(x>a[mid]) right=mid-1; else left=mid+1; } return-1; } intmain() { inta[100]; cout<<"请输入数组中数的个数,小于100: "; intnum=0; cin>>num; cout<<"请输入数组中的数: "< for(inti=0;i cin>>a[i]; //下面将数组a排成升序 BubbleSort(a,num); cout<<"下面输出排序后的数组: "< for(i=0;i printf("%4d",a[i]); cout< cout<<"请输入要查找的数: "; intx=0; cin>>x; intj=0; if(BinarySearch(a,num,x,i,j)) cout<<"找到了,位置为"< else cout<<"没找到,小于该数的最大元素位置为"< return0; } 试运行调试结果如下: 运行结果如下图所示: 实验题2编写代码如下: #include usingnamespacestd; /*根据题目中的隐含要求,现在将问题进行简化,假设数组中存放的数全部为整数*/ voidBubbleSort(int*pData,intCount) //冒泡排序的函数,pData中从0位置处存了Count个数,该函数将数组中元素排升序 { intiTemp; for(inti=1;i { for(intj=Count-1;j>=i;j--) { if(pData[j] { iTemp=pData[j-1]; pData[j-1]=pData[j]; pData[j]=iTemp; } } } } boolBinaryFind_iei(inta[],intn,int&i) //数组a大小为n,数组中存放了已经排好序(升序)的数列 { intleft=0; intright=n-1; intmid=0; while(left { mid=(left+right)/2; if(mid==a[mid]) { i=mid; returntrue; //找到了 } else if(mid>a[mid]) left=mid; else right=mid; } returnfalse; } intmain() { inta[100]; cout<<"请输入数组中数的个数,小于100: "; intnum=0; cin>>num; cout<<"请输入数组中的数: "< for(intii=0;ii cin>>a[ii]; //下面将数组a排成升序 BubbleSort(a,num); cout<<"下面输出排序后的数组: "< for(inti=0;i printf("%4d",a[i]); cout< intj=0; if(BinaryFind_iei(a,num,j)) cout<<"找到了,位置为"< else cout<<"不存在符合第i个位置等于i的元素。 "< return0; } 试运行调试结果如下: 运行结果如下: 结果分析: 利用分治策略求解时,所需时间取决于分解后子问题的个数、子问题的规模大小等素,而二分法,由于其划分的简单和均匀的特点,是经常采用的一种有效的方法,例如二分法检索。 提高题二: 用分治法实现元素选择 一、实验要求与目的 1、了解分治法的基本思想,掌握递归程序编写方法; 2、使用分治法编程,求解线形序列中第k小元素。 二、实验内容 1、给定线形序列集中n个元素和一个整数k,1≤k≤n,输出这n个元素中第k小元素的值及其位置。 2、简述该算法的原理、步骤。 对该算法与直接排序查找进行比较。 3、编写并调试程序。 测试要求: 元素个数不少于100;分三种情况: k=1、k=n和k=中位数。 编写程序代码如下所示: #include #include #include #include intpartition(inta[],intp,intr) { intz=p,x=r+1; inty=a[p]; intt; while (1) { while(a[++z] while(a[--x]>y); if(z>=x)break; t=a[z]; a[z]=a[x]; a[x]=t; } a[p]=a[x]; a[x]=y; returnx; } voidquicksort(inta[],intp,intr) { intq; if(p { q=partition(a,p,r); quicksort(a,p,q-1); quicksort(a,q+1,r); } } intmain() { for(;;) { intk,*a,*b,n,i,d,s; printf("请输入数组个数: "); scanf("%d",&n); printf("\n"); a=(int*)malloc(sizeof(int)*n);//给数组a分配空间 srand((unsigned)time(NULL)); b=(int*)malloc(sizeof(int)*n);//给数组b分配空间 srand((unsigned)time(NULL)); for(i=0;i { a[i]=rand()%100+1;//产生小于100的数据 } for(i=0;i { printf("%d\t",a[i]); if((i+1)%10==0)//每行10个数据 printf("\n"); } printf("\n"); for(i=0,d=0;d { b[d]=a[i]; i++; } quicksort(a,0,i-1);//调用快速排序进行排序 printf("排序后"); printf("\n"); for(i=0;i { printf("%d\t",a[i]); if((i+1)%10==0)//输出排好序的数组a,每行10个数据 printf("\n"); } printf("\n"); printf("请输入第k小元素: "); scanf("%d",&k); for(d=0;d { if(b[d]==a[k-1])//从数组b中找出第k小的数在原数组中的位置 s=d+1; } printf("第%d小元素为: %d",k,a[k-1]); printf("\n"); printf("第%d小元素位置为: %d",k,s); printf("\n"); system("pause"); printf("\n"); } } 试运行调试结果如下: 运行结果如下: 测试一: K=1 测试二: K=n(此处为K=n=102) 测试三: k=中位数 五: 实验总结 通过此次实验进一步熟悉了C/C++语言的集成开发环境以及进一步加深了对递归过程的理解,理论结合实际让自己对此阶段的知识掌握的更加牢固,收益颇丰。 如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。 copyright@ 2008-2022 冰点文档网站版权所有 经营许可证编号:鄂ICP备2022015515号-1=tc+s) =tc+s)
冰豆网所有资源均是用户自行上传分享,仅供网友学习交流,未经上传用户书面授权,请勿作他用。