ImageVerifierCode 换一换
格式:DOCX , 页数:12 ,大小:150.48KB ,
资源ID:8022773      下载积分:3 金币
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,免费下载
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.bdocx.com/down/8022773.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(用栈模拟递归+集合划分问题+众数问题+数塔问题.docx)为本站会员(b****5)主动上传,冰豆网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰豆网(发送邮件至service@bdocx.com或直接QQ联系客服),我们立即给予删除!

用栈模拟递归+集合划分问题+众数问题+数塔问题.docx

1、用栈模拟递归+集合划分问题+众数问题+数塔问题专业班级:计科2班 学号:20110801212 姓名:张琦佳一、2-24试用栈来模拟递归,消去算法QuickSort中的尾递归,并比较消去尾递归前后算法的效率。1、解题说明快速排序的递归算法思路是,将整个数组以轴值为界限划分为两部分,然后分别最两部分进行快速排序。而用栈来模拟递归,其实就是用栈保存每一个待排序子串的首尾元素下表,下一次while循环的时候来,对这段子序列进行partition操作。快速排序的算法在上学期的数据结构中已经学习过,只需对其中的qsort()函数中的递归部分进行修改即可。调用库函数计算程序运行时间,并输出,便于对比两种算

2、法的效率。2、代码#include#include#include#include#includeusing namespace std;DWORD take;int findpivot(int A,int i,int j) /找到轴值 srand(unsigned(time(0); /取随机数 int pivot1=rand()%(j-i+1)+i; /取轴值 return pivot1; void swap(int A,int i,int j) /交换 int temp=Ai; Ai=Aj; Aj=temp;int partition(int A,int l,int r,int& pivo

3、t) /分组 do while(A+lpivot); /将r左移 swap(A,l,r); /交换 while(lr); swap(A,l,r); /多交换1次,交换回来 return l;/递归算法void qsort(int A,int i,int j) /快速排序 if(j=i) return; /只剩一个元素的时候停止分组 int pivotindex=findpivot(A,i,j); /获取轴值 swap(A,pivotindex,j); /将轴值放在最后 int k=partition(A,i-1,j,Aj); /右半部分的第一个值 swap(A,k,j); /将轴值换回来 qs

4、ort(A,i,k-1); /递归 qsort(A,k+1,j);/非递归算法void qsort2(int A,int i,int j) stack st; if(j=i) return; /只剩一个元素的时候停止分组 int pivotindex=findpivot(A,i,j);/获取轴值 swap(A,pivotindex,j); /将轴值放在最后 int k=partition(A,i-1,j,Aj);/右半部分的第一个值 swap(A,k,j); /将轴值换回来 if(ik-1) /用栈保存每个待排序子串的首尾元素下标 st.push(i); st.push(k-1); if(k+

5、1j) st.push(k+1); st.push(j); while(!st.empty() int q=st.top(); st.pop(); int p=st.top(); st.pop(); int pivotindex=findpivot(A,p,q); swap(A,pivotindex,q); int k=partition(A,p-1,q,Aq); swap(A,k,q); if(pk-1) st.push(p); st.push(k-1); if(k+1q) st.push(k+1); st.push(q); int main() take=GetTickCount(); i

6、nt n; int task100; cout请输入待排序的数据个数n: n; cout输入数据: endl; for(int i=0;itaski; qsort(task,0,n-1);/qsort2(task,0,n-1); cout排序结果为:endl; for(int j=0;jn;j+) couttaskjendl; cout运行时间为:takeendl; return 0;3、运行截图非递归算法:递归算法:可以看出,非递归算法的运算速度更快些,若数据个数增大,差距会更加明显。4、递归与非递归效率对比 理论来说,由于递归要层层调用,容易栈溢出,当算法比较复杂的时候,效率也非常低,运行

7、起来等待结果时间很长。而用非递归,减少了函数调用开销,可以解决溢出问题和效率低的问题。 因为递归算法使用的栈由程序自动产生,栈中包含函数调用时的参数和函数中的局部变量。如果局部变量很多或者函数内部又调用了其他函数,则栈会很大。每次递归调用都要操作很大的栈,效率自然会下降。而对于非递归算法,每次循环使用自己预先创建的栈,因此不管程序复杂度如何,都不会影响程序效率。二、2-2 众数问题 问题描述:给定含有n个元素的多重集合S,每个元素在S中出现的次数称为该元素的重数。例如,S=1,2,2,2,3,5。多重集S的众数是2,其重数为3。 算法设计:对于给定的由n个自然数组成的多重集S,计算S的众数及其

8、重数。数据输入:输入数据由文件名为input.txt的文本文件提供。文件的第1行为多重集S中元素个数n;在接下来的n行中,每行有一个自然数。结果输出:将计算结果输出到文件output.txt。输出文件有2行,第1行是众数,第2行是重数。 输入文件示例 输出文件示例 input.txt output.txt 6 2 1 3 2 2 2 3 51、解题说明 首先将文件中数据读入到一个数组中,要想选择众数,最基本的方法就是写一个双重for循环,每一个元素跟数组中其他元素对比一遍,这样时间复杂度是n的平方。改进方案是先调用库函数sort,对数组进行排序,则只用一个for循环便可得到众数和重数。2、代码

9、#include#include#includeusing namespace std;int main() int n,amount=1,maxamount=1,maxindex; ifstream in(input.txt); ofstream out(output.txt); inn; /从文件读入元素个数 int *a=new intn; for(int i=0;iai; /从文件读入元素 sort(a,a+n); /对元素数组进行从小到大排序 for(int j=1;jmaxamount) maxamount=amount; maxindex=j; outamaxindexendlm

10、axamountendl; /将输出写入文件中 return 0;3、程序运行截图input.txt: output.txt: 输入输出文件都在当前目录下: 三、2-10集合划分问题对于给定正整数n,计算出n个元素的集合1,2,n可以划分为多少个不同的非空子集。数据输入:由文件input.txt提供输入数据。文件的第1行是元素个数n。结果输出:将计算出的不同的非空子集数输出到文件output.txt。 输入文件示例 输出文件示例 input.txt output.txt5 521、解题说明 将n个元素划分为m个集合的递归思路如下:把n个元素编号,对于第n个元素,有两种情况,第一种是自己单独是一

11、个集合,等价于把前n-1个元素分成m-1份;第二种是第n个元素和别的元素一起组成了一个集合,等价于把前n-1个元素分成m份,然后把n号元素放入这m个集合中的一个(即有m中放法)。 所以总数是:F(n,m)=F(n-1,m-1)+F(n-1,m)*m因此要求所有的集合,只需再用一个for循环,将划分大小从1循环到n即可。2、代码#include#includeusing namespace std;int partition(int n,int m) if(m=1|m=n) return 1; else return partition(n-1,m-1)+partition(n-1,m)*m;i

12、nt main() int n,sum=0; ifstream in(input.txt); ofstream out(output.txt); inn; for(int i=1;i=n;i+) sum+=partition(n,i); outsumendl; return 0;3、运行截图input.txtoutput.txt输入输出文件都存储在当前目录下:四、数塔问题输入如下:第一行的数字代表数塔的层数,接下来的数字为数塔中各层的结点中保存的数字1、解题说明这个题是典型的动态规划问题,考虑的时候自顶向下的分析,自底向上的计算。从顶点出发,向左走还是向右走取决于走哪边最终总路径和最大,只有两

13、条路径的总长度最大值求出了才能做决策,一层一层推下去,直到倒数第二层,它选择左还是右,只取决于哪个数更大些。所以实际求解的时候,可以从底层开始,层层往上推算,最后得到最大值。2、代码#include#includeusing namespace std;int max(int a,int b) /求最大值函数 return ab?a:b;int main() int i,j,n,* a; ifstream in(input.txt); ofstream out(output.txt); inn; a=new int*n+1; /创建二维数组存放数塔 for(i=0;in+1;i+) ai=new intn+1; for(i=1;in+1;i+) /从文件中读取数塔中的数字,存放到二维数组中 for(j=1;jaij; for(i=n-1;i=1;i-) /从倒数第二层开始,从下往上求最大值路径 for(j=1;j=i;j+) aij+=max(ai+1j,ai+1j+1); outa11endl; return 0;3、运行截图input.txtoutput.txt 输入输出文件在当前文件夹下:

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1