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