数据结构和算法部分经典例子.doc
《数据结构和算法部分经典例子.doc》由会员分享,可在线阅读,更多相关《数据结构和算法部分经典例子.doc(35页珍藏版)》请在咨信网上搜索。
1、数据结构和算法部分经典例子 一、迭代法 迭代法是用于求方程或方程组近似根的一种常用的算法设计方法.设方程为f(x)=0,用某种数学方法导出等价的形式x=g(x),然后按以下步骤执行: (1) 选一个方程的近似根,赋给变量x0; (2) 将x0的值保存于变量x1,然后计算g(x1),并将结果存于变量x0; (3) 当x0与x1的差的绝对值还小于指定的精度要求时,重复步骤(2)的计算. 若方程有根,并且用上述方法计算出来的近似根序列收敛,则按上述方法求得的x0就认为是方程的根。上述算法用C程序的形式表示为: 【算法】迭代法求方程的根 x0=初始近似根; do x1=x0; x0=g(x1); /*
2、按特定的方程计算新的近似根*/ while ( fabs(x0x1)Epsilon); printf(“方程的近似根是fn”,x0); 迭代算法也常用于求方程组的根,令 X=(x0,x1,xn-1) 设方程组为: xi=gi(X) (I=0,1,,n1) 则求方程组根的迭代算法可描述如下: 【算法】迭代法求方程组的根 for (i=0;in;i+) xi=初始近似根; do for (i=0;in;i+) yi=xi; for (i=0;in;i+) xi=gi(X); for (delta=0.0,i=0;in;i+) if (fabs(yixi)delta) delta=fabs(yixi
3、); while (deltaEpsilon); for (i=0;in;i+) printf(“变量xd的近似根是 f”,I,xi); printf(“n); 具体使用迭代法求根时应注意以下两种可能发生的情况: (1) 如果方程无解,算法求出的近似根序列就不会收敛,迭代过程会变成死循环,因此在使用迭代算法前应先考察方程是否有解,并在程序中对迭代的次数给予限制; (2) 方程虽然有解,但迭代公式选择不当,或迭代的初始近似根选择不合理,也会导致迭代失败。 二、穷举搜索法 本文为互联网收集,请勿用作商业用途穷举搜索法是对可能是解的众多候选解按某种顺序进行逐一枚举和检验,并从众找出那些符合要求的候选
4、解作为问题的解. 【问题】 将A、B、C、D、E、F这六个变量排成如图所示的三角形,这六个变量分别取1,6上的整数,且均不相同。求使三角形三条边上的变量之和相等的全部解。如图就是一个解。 程序引入变量a、b、c、d、e、f,并让它们分别顺序取1至6的证书,在它们互不相同的条件下,测试由它们排成的如图所示的三角形三条边上的变量之和是否相等,如相等即为一种满足要求的排列,把它们输出。当这些变量取尽所有的组合后,程序就可得到全部可能的解.细节见下面的程序. 【程序1】 # include stdio.h void main() int a,b,c,d,e,f; for (a=1;a=6;a+) fo
5、r (b=1;b=6;b+) if (b=a) continue; for (c=1;c=6;c+) if (c=a)|(c=b) continue; for (d=1;d=6;d+) if (d=a)(d=b)|(d=c) continue; for (e=1;e=6;e+) if (e=a)|(e=b)|(e=c)(e=d) continue; f=21-(a+b+c+d+e); if (a+b+c=c+d+e))(a+b+c=e+f+a) printf(“6d,a); printf(“4d%4d”,b,f); printf(“2d4d%4d,c,d,e); scanf(“%*c”); 按
6、穷举法编写的程序通常不能适应变化的情况.如问题改成有9个变量排成三角形,每条边有4个变量的情况,程序的循环重数就要相应改变. 对一组数穷尽所有排列,还有更直接的方法。将一个排列看作一个长整数,则所有排列对应着一组整数。将这组整数按从小到大的顺序排列排成一个整数,从对应最小的整数开始.按数列的递增顺序逐一列举每个排列对应的每个整数,这能更有效地完成排列的穷举。从一个排列找出对应数列的下一个排列可在当前排列的基础上作部分调整来实现。倘若当前排列为1,2,4,6,5,3,并令其对应的长整数为124653。要寻找比长整数124653更大的排列,可从该排列的最后一个数字顺序向前逐位考察,当发现排列中的某
7、个数字比它前一个数字大时,如本例中的6比它的前一位数字4大,这说明还有对应更大整数的排列。但为了顺序从小到大列举出所有的排列,不能立即调整得太大,如本例中将数字6与数字4交换得到的排列126453就不是排列124653的下一个排列.为了得到排列124653的下一个排列,应从已经考察过的那部分数字中选出比数字大,但又是它们中最小的那一个数字,比如数字5,与数字4交换。该数字也是从后向前考察过程中第一个比4大的数字.5与4交换后,得到排列125643。在前面数字1,2,5固定的情况下,还应选择对应最小整数的那个排列,为此还需将后面那部分数字的排列顺序颠倒,如将数字6,4,3的排列顺序颠倒,得到排列
8、1,2,5,3,4,6,这才是排列1,2,4,6,5,3的下一个排列。按以上想法编写的程序如下。 个人收集整理,勿做商业用途2 数据结构(ZT) 【程序2】 # include stdio.h # define SIDE_N 3 # define LENGTH 3 define VARIABLES 6 int A,B,C,D,E,F; int *pt=A,B,C,&D,E,&F; int *sideSIDE_NLENGTH=A,B,C,&C,D,&E,E,&F,&A; int side_totalSIDE_N; main int i,j,t,equal; for (j=0;jVARIABLES
9、;j+) ptj=j+1; while(1) for (i=0;iSIDE_N;i+) for (t=j=0;jLENGTH;j+) t+=sideij; side_totali=t; for (equal=1,i=0;equal&i0;j-) if (*ptjptj-1) break; if (j=0) break; for (i=VARIABLES1;i=j;i-) if (pti*pti-1) break; t=ptj-1;* ptj-1 = pti; pti=t; for (i=VARIABLES1;ij;i-,j+) t=*ptj; *ptj =* pti; *pti=t; 从上述问
10、题解决的方法中,最重要的因素就是确定某种方法来确定所有的候选解。下面再用一个示例来加以说明。 【问题】 背包问题 问题描述:有不同价值、不同重量的物品n件,求从这n件物品中选取一部分物品的选择方案,使选中物品的总重量不超过指定的限制重量,但选中物品的价值之和最大。 设n个物品的重量和价值分别存储于数组w 和v 中,限制重量为tw.考虑一个n元组(x0,x1,xn-1),其中xi=0 表示第i个物品没有选取,而xi=1则表示第i个物品被选取。显然这个n元组等价于一个选择方案。用枚举法解决背包问题,需要枚举所有的选取方案,而根据上述方法,我们只要枚举所有的n元组,就可以得到问题的解。 显然,每个分
11、量取值为0或1的n元组的个数共为2n个。而每个n元组其实对应了一个长度为n的二进制数,且这些二进制数的取值范围为02n1。因此,如果把02n1分别转化为相应的二进制数,则可以得到我们所需要的2n个n元组。 【算法】 maxv=0; for (i=0;i2n;i+) B0。.n-1=0; 把i转化为二进制数,存储于数组B中; temp_w=0; temp_v=0; for (j=0;jmaxv)) maxv=temp_v; 保存该B数组; 三、递推法 递推法是利用问题本身所具有的一种递推关系求问题解的一种方法。设要求问题规模为N的解,当N=1时,解或为已知,或能非常方便地得到解。能采用递推法构造
12、算法的问题有重要的递推性质,即当得到问题规模为i1的解后,由问题的递推性质,能从已求得的规模为1,2,i-1的一系列解,构造出问题规模为I的解。这样,程序可从i=0或i=1出发,重复地,由已知至i1规模的解,通过递推,获得规模为i的解,直至得到规模为N的解。 【问题】 阶乘计算 问题描述:编写程序,对给定的n(n100),计算并输出k的阶乘k!(k=1,2,,n)的全部有效数字. 由于要求的整数可能大大超出一般整数的位数,程序用一维数组存储长整数,存储长整数数组的每个元素只存储长整数的一位数字。如有m位成整数N用数组a 存储: N=am10m1+am110m-2+ +a2101+a1100 并
13、用a0存储长整数N的位数m,即a0=m。按上述约定,数组的每个元素存储k的阶乘k!的一位数字,并从低位到高位依次存于数组的第二个元素、第三个元素.例如,5!=120,在数组中的存储形式为: 个人收集整理,勿做商业用途3 数据结构(ZT) 3 0 2 1 首元素3表示长整数是一个3位数,接着是低位到高位依次是0、2、1,表示成整数120。 计算阶乘k!可采用对已求得的阶乘(k1)!连续累加k1次后求得.例如,已知4!=24,计算5!,可对原来的24累加4次24后得到120。细节见以下程序。 include stdio.h include malloc.h # define MAXN 1000 v
14、oid pnext(int a ,int k) int *b,m=a0,i,j,r,carry; b=(int ) malloc(sizeof(int) (m+1); for ( i=1;i=m;i+) bi=ai; for ( j=1;j=k;j+) for ( carry=0,i=1;i0;i) printf(“%d”,ai); printf(“nn”); void main() int aMAXN,n,k; printf(“Enter the number n: “); scanf(“%d,n); a0=1; a1=1; write(a,1); for (k=2;k1时)。 写成递归函数
15、有: int fib(int n) if (n=0) return 0; if (n=1) return 1; if (n1) return fib(n-1)+fib(n2); 递归算法的执行过程分递推和回归两个阶段。在递推阶段,把较复杂的问题(规模为n)的求解推到比原问题简单一些的问题(规模小于n)的求解.例如上例中,求解fib(n),把它推到求解fib(n1)和fib(n-2).也就是说,为计算fib(n),必须先计算fib(n-1)和fib(n-2),而计算fib(n-1)和fib(n2),又必须先计算fib(n-3)和fib(n4)。依次类推,直至计算fib(1)和fib(0),分别能
16、立即得到结果1和0。在递推阶段,必须要有终止递归的情况。例如在函数fib中,当n为1和0的情况。 在回归阶段,当获得最简单情况的解后,逐级返回,依次得到稍复杂问题的解,例如得到fib(1)和fib(0)后,返回得到fib(2)的结果,在得到了fib(n-1)和fib(n2)的结果后,返回得到fib(n)的结果. 在编写递归函数时要注意,函数中的局部变量和参数知识局限于当前调用层,当递推进入“简单问题层时,原来层次上的参数和局部变量便被隐蔽起来.在一系列“简单问题层,它们各有自己的参数和局部变量。 由于递归引起一系列的函数调用,并且可能会有一系列的重复计算,递归算法的执行效率相对较低.当某个递归
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 数据结构 算法 部分 经典 例子
1、咨信平台为文档C2C交易模式,即用户上传的文档直接被用户下载,收益归上传人(含作者)所有;本站仅是提供信息存储空间和展示预览,仅对用户上传内容的表现方式做保护处理,对上载内容不做任何修改或编辑。所展示的作品文档包括内容和图片全部来源于网络用户和作者上传投稿,我们不确定上传用户享有完全著作权,根据《信息网络传播权保护条例》,如果侵犯了您的版权、权益或隐私,请联系我们,核实后会尽快下架及时删除,并可随时和客服了解处理情况,尊重保护知识产权我们共同努力。
2、文档的总页数、文档格式和文档大小以系统显示为准(内容中显示的页数不一定正确),网站客服只以系统显示的页数、文件格式、文档大小作为仲裁依据,个别因单元格分列造成显示页码不一将协商解决,平台无法对文档的真实性、完整性、权威性、准确性、专业性及其观点立场做任何保证或承诺,下载前须认真查看,确认无误后再购买,务必慎重购买;若有违法违纪将进行移交司法处理,若涉侵权平台将进行基本处罚并下架。
3、本站所有内容均由用户上传,付费前请自行鉴别,如您付费,意味着您已接受本站规则且自行承担风险,本站不进行额外附加服务,虚拟产品一经售出概不退款(未进行购买下载可退充值款),文档一经付费(服务费)、不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
4、如你看到网页展示的文档有www.zixin.com.cn水印,是因预览和防盗链等技术需要对页面进行转换压缩成图而已,我们并不对上传的文档进行任何编辑或修改,文档下载后都不会有水印标识(原文档上传前个别存留的除外),下载后原文更清晰;试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓;PPT和DOC文档可被视为“模板”,允许上传人保留章节、目录结构的情况下删减部份的内容;PDF文档不管是原文档转换或图片扫描而得,本站不作要求视为允许,下载前自行私信或留言给上传者【a199****6536】。
5、本文档所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用;网站提供的党政主题相关内容(国旗、国徽、党徽--等)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。
6、文档遇到问题,请及时私信或留言给本站上传会员【a199****6536】,需本站解决可联系【 微信客服】、【 QQ客服】,若有其他问题请点击或扫码反馈【 服务填表】;文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“【 版权申诉】”(推荐),意见反馈和侵权处理邮箱:1219186828@qq.com;也可以拔打客服电话:4008-655-100;投诉/维权电话:4009-655-100。