数据结构经典问题和算法分析

上传人:壹****1 文档编号:28516965 上传时间:2018-01-17 格式:DOC 页数:43 大小:166.50KB
返回 下载 相关 举报
数据结构经典问题和算法分析_第1页
第1页 / 共43页
数据结构经典问题和算法分析_第2页
第2页 / 共43页
数据结构经典问题和算法分析_第3页
第3页 / 共43页
数据结构经典问题和算法分析_第4页
第4页 / 共43页
数据结构经典问题和算法分析_第5页
第5页 / 共43页
点击查看更多>>
资源描述

《数据结构经典问题和算法分析》由会员分享,可在线阅读,更多相关《数据结构经典问题和算法分析(43页珍藏版)》请在金锄头文库上搜索。

1、数据结构经典问题和算法分析(一)-迭代法来源: 作者: 2007-5-30 21:17:53 字体: 大 中 小 一、迭代法 迭代法是用于求方程或方程组近似根的一种常用的算法设计方法。设方程为 f(x)=0,用某种数学方法导出等价的形式 x=g(x),然后按以下步骤执行: (1) 选一个方程的近似根,赋给变量 x0; (2) 将 x0 的值保存于变量 x1,然后计算 g(x1),并将结果存于变量 x0; (3) 当 x0 与 x1 的差的绝对值还小于指定的精度要求时,重复步骤(2)的计算。 若方程有根,并且用上述方法计算出来的近似根序列收敛,则按上述方法求得的 x0 就认为是方程的根。上述算法

2、用 C 程序的形式表示为: 【算法】迭代法求方程的根 x0=初始近似根; do x1=x0; x0=g(x1); /*按特定的方程计算新的近似根*/ while ( fabs(x0-x1)Epsilon); printf(“方程的近似根是 %fn”,x0); 迭代算法也常用于求方程组的根,令 X=(x0,x1,xn-1 ) 设方程组为: xi=gi(X) (I=0,1 ,n-1) 则求方程组根的迭代算法可描述如下: 【算法】迭代法求方程组的根 for (i=0;idelta) delta=fabs(yi-xi); while (deltaEpsilon); for (i=0;i void ma

3、in() int a,b,c,d,e,f; for (a=1;a # define SIDE_N 3 # define LENGTH 3 # define VARIABLES 6 int A,B,C,D,E,F; int *pt= int *sideSIDE_NLENGTH= int side_totalSIDE_N; main int i,j,t,equal; for (j=0;j0;j-) if (*ptj*ptj-1) break; if (j=0) break; for (i=VARIABLES-1;i=j;i-) if (*pti*pti-1) break; t=*ptj-1;* p

4、tj-1 =* pti; *pti=t; for (i=VARIABLES-1;ij;i-,j+) t=*ptj; *ptj =* pti; *pti=t; 从上述问题解决的方法中,最重要的因素就是确定某种方法来确定所有的候选解。下面再用一个示例来加以说明。 【问题】 背包问题 问题描述:有不同价值、不同重量的物品 n 件,求从这 n 件物品中选取一部分物品的选择方案,使选中物品的总重量不超过指定的限制重量,但选中物品的价值之和最大。 设 n 个物品的重量和价值分别存储于数组 w 和 v 中,限制重量为 tw。考虑一个 n 元组(x0,x1,xn-1),其中 xi=0 表示第 i 个物品没有选

5、取,而 xi=1 则表示第 i 个物品被选取。显然这个 n 元组等价于一个选择方案。用枚举法解决背包问题,需要枚举所有的选取方案,而根据上述方法,我们只要枚举所有的 n 元组,就可以得到问题的解。 显然,每个分量取值为 0 或 1 的 n 元组的个数共为 2n 个。而每个 n 元组其实对应了一个长度为 n 的二进制数,且这些二进制数的取值范围为 02n-1 。因此,如果把 02n-1分别转化为相应的二进制数,则可以得到我们所需要的 2n 个 n 元组。 【算法】 maxv=0; for (i=0;imaxv) maxv=temp_v; 保存该 B 数组; 数据结构经典问题和算法分析(三)递推法

6、来源: 作者: 2007-5-30 21:31:13 字体: 大 中 小 三、递推法 递推法是利用问题本身所具有的一种递推关系求问题解的一种方法。设要求问题规模为N 的解,当 N=1 时,解或为已知,或能非常方便地得到解。能采用递推法构造算法的问题有重要的递推性质,即当得到问题规模为 i-1 的解后,由问题的递推性质,能从已求得的规模为 1,2,i-1 的一系列解,构造出问题规模为 I 的解。这样,程序可从 i=0 或 i=1出发,重复地,由已知至 i-1 规模的解,通过递推,获得规模为 i 的解,直至得到规模为N 的解。 【问题】 阶乘计算 问题描述:编写程序,对给定的 n(n100),计算

7、并输出 k 的阶乘k!(k=1,2, ,n)的全部有效数字。 由于要求的整数可能大大超出一般整数的位数,程序用一维数组存储长整数,存储长整数数组的每个元素只存储长整数的一位数字。如有 m 位成整数 N 用数组 a 存储: N=am10m-1+am-110m-2+ +a2101+a1100 并用 a0存储长整数 N 的位数 m,即 a0=m。按上述约定,数组的每个元素存储 k 的阶乘 k!的一位数字,并从低位到高位依次存于数组的第二个元素、第三个元素。例如,5!=120 ,在数组中的存储形式为: 3 0 2 1 首元素 3 表示长整数是一个 3 位数,接着是低位到高位依次是 0、2、1 ,表示成

8、整数120。 计算阶乘 k!可采用对已求得的阶乘(k-1)!连续累加 k-1 次后求得。例如,已知4!=24,计算 5!,可对原来的 24 累加 4 次 24 后得到 120。细节见以下程序。 # include # include # define MAXN 1000 void pnext(int a ,int k) int *b,m=a0,i,j,r,carry; b=(int * ) malloc(sizeof(int)* (m+1); for ( i=1;i0;i-) printf(“%d”,ai); printf(“nn”); void main() int aMAXN,n,k; p

9、rintf(“Enter the number n: “); scanf(“%d”, a0=1; a1=1; write(a,1); for (k=2;k1 时)。 写成递归函数有: int fib(int n) if (n=0) return 0; if (n=1) return 1; if (n1) return fib(n-1)+fib(n-2); 递归算法的执行过程分递推和回归两个阶段。在递推阶段,把较复杂的问题(规模为n)的求解推到比原问题简单一些的问题(规模小于 n)的求解。例如上例中,求解 fib(n),把它推到求解 fib(n-1)和 fib(n-2)。也就是说,为计算 fib

10、(n),必须先计算 fib(n-1)和 fib(n-2),而计算 fib(n-1)和 fib(n-2),又必须先计算 fib(n-3)和 fib(n-4)。依次类推,直至计算 fib(1)和fib(0),分别能立即得到结果 1 和 0。在递推阶段,必须要有终止递归的情况。例如在函数fib 中,当 n 为 1 和 0 的情况。 在回归阶段,当获得最简单情况的解后,逐级返回,依次得到稍复杂问题的解,例如得到 fib(1)和 fib(0)后,返回得到 fib(2)的结果,在得到了 fib(n-1)和 fib(n-2)的结果后,返回得到 fib(n)的结果。 在编写递归函数时要注意,函数中的局部变量和

11、参数知识局限于当前调用层,当递推进入“简单问题” 层时,原来层次上的参数和局部变量便被隐蔽起来。在一系列“简单问题”层,它们各有自己的参数和局部变量。 由于递归引起一系列的函数调用,并且可能会有一系列的重复计算,递归算法的执行效率相对较低。当某个递归算法能较方便地转换成递推算法时,通常按递推算法编写程序。例如上例计算斐波那契数列的第 n 项的函数 fib(n)应采用递推算法,即从斐波那契数列的前两项出发,逐次由前两项计算出下一项,直至计算出要求的第 n 项。 【问题】 组合问题 问题描述:找出从自然数 1、2、n 中任取 r 个数的所有组合。例如 n=5,r=3 的所有组合为: (1)5、4

12、、3 (2)5、4、2 (3)5、4、1 (4)5、3、2 (5)5、3、1 (6)5 、2 、1 (7 )4、3、2 (8 )4、3、1 (9)4、2、1 (10)3、2、1 分析所列的 10 个组合,可以采用这样的递归思想来考虑求组合函数的算法。设函数为void comb(int m,int k)为找出从自然数 1、2、m 中任取 k 个数的所有组合。当组合的第一个数字选定时,其后的数字是从余下的 m-1 个数中取 k-1 数的组合。这就将求 m 个数中取 k 个数的组合问题转化成求 m-1 个数中取 k-1 个数的组合问题。设函数引入工作数组 a 存放求出的组合的数字,约定函数将确定的

13、k 个数字组合的第一个数字放在 ak中,当一个组合求出后,才将 a 中的一个组合输出。第一个数可以是 m、m-1 、k,函数将确定组合的第一个数字放入数组后,有两种可能的选择,因还未去顶组合的其余元素,继续递归去确定;或因已确定了组合的全部元素,输出这个组合。细节见以下程序中的函数 comb。 【程序】 # include # define MAXN 100 int aMAXN; void comb(int m,int k) int i,j; for (i=m;i=k;i-) ak=i; / am-a1 store the combinationif (k1) comb(i-1,k-1); e

14、lse for (j=a0;j0;j-) printf(“%4d”,aj); printf(“n”); void main() a0=3; comb(5,3); 【问题】 背包问题 问题描述:有不同价值、不同重量的物品 n 件,求从这 n 件物品中选取一部分物品的选择方案,使选中物品的总重量不超过指定的限制重量,但选中物品的价值之和最大。 设 n 件物品的重量分别为 w0、w1 、wn-1 ,物品的价值分别为 v0、v1、vn-1 。采用递归寻找物品的选择方案。设前面已有了多种选择的方案,并保留了其中总价值最大的方案于数组 option ,该方案的总价值存于变量 maxv。当前正在考察新方案,其物品选择情况保存于数组 cop 。假定当前方案已考虑了前 i-1 件物品,现在要考虑第 i 件物品;当前方案已包含的物品的重量之和为 tw;至此,若其余物品都选择是可能的话,本方案能达到的总价值的期望值为 tv。算法引入 tv 是当一旦当前方案的总价值的期望值也小于前面方案的总价值 maxv 时,继续考察当前方案变成无意义的工作,应终止当前方案,立即去考察下一个方案。因为当方案的总价值不比 maxv 大时,该方案不会被再考察,这同时保证函数后找到的方案一定会比前面的方案更好。 对于第 i 件物品的选择考虑有两种可

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 建筑/环境 > 建筑规划

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号