导航:首页 > 源码编译 > 递归算法在桥梁中的应用论文

递归算法在桥梁中的应用论文

发布时间:2022-05-10 05:46:46

‘壹’ 递归算法的特性

递归算法两个特性
1.递归算法是一种分而治之,把复杂问题分解为简单问题的求解问题方法,对求解某些复杂问题,递归算法的分析方法是有效地。
2递归算法的时间效率低

‘贰’ 什么是递归算法有什么作用

作者名:不详 来源:网友提供 05年7月7日

无法贴图 ,自己到 http://51zk.csai.cn/sjjg/NO00223.htm 看去吧

1、调用子程序的含义:
在过程和函数的学习中,我们知道调用子程序的一般形式是:主程序调用子程序A,子程序A调用子程序B,如图如示,这个过程实际上是:

@当主程序执行到调用子程序A语句时,系统保存一些必要的现场数据,然后执行类似于BASIC语言的GOTO语句,跳转到子程序A(为了说得简单些,我这里忽略了参数传递这个过程)。
@当子程序A执行到调用子程序B语句时,系统作法如上,跳转到子程序B。
@子程序B执行完所有语句后,跳转回子程序A调用子程序B语句的下一条语句(我这又忽略了返回值处理)
@子程序A执行完后,跳转回主程序调用子程序A语句的下一条语句
@主程序执行到结束。
做个比较:我在吃饭(执行主程序)吃到一半时,某人叫我(执行子程序A),话正说到一半,电话又响了起来(执行子程序B),我只要先接完电话,再和某人把话说完,最后把饭吃完(我这饭吃得也够累的了J)。
2、认识递归函数
我们在高中时都学过数学归纳法,例:
求 n!
我们可以把n!这么定义

也就是说要求3!,我们必须先求出2!,要求2!,必须先求1!,要求1!,就必须先求0!,而0!=1,所以1!=0!*1=1,再进而求2!,3!。分别用函数表示,则如图:

我们可以观察到,除计算0!子程序外,其他的子程序基本相似,我们可以设计这么一个子程序:
int factorial(int i){
int res;
res=factorial(I-1)*i;
return res;
}
那么当执行主程序语句s=factorial(3)时,就会执行factorial(3),但在执行factorial(3),又会调用factorial(2),这时大家要注意,factorial(3)和factorial(2)虽然是同一个代码段,但在内存中它的数据区是两份!而执行factorial(2)时又会调用factorial(1),执行factorial(1)时又会调用factorial(0),每调用一次factorial函数,它就会在内存中新增一个数据区,那么这些复制了多份的函数大家可以把它看成是多个不同名的函数来理解;
但我们这个函数有点问题,在执行factorial(0)时,它又会调用factorial(-1)。。。造成死循环,也就是说,在factorial函数中,我们要在适当的时候保证不再调用该函数,也就是不执行res=factorial(I-1)*i;这条调用语句。所以函数要改成:
int factorial(int i){
int res;
if (I>0) res=factorial(I-1)*i; else res=1;
return res;
}
那么求3!的实际执行过程如图所示:

3、如何考虑用递归的方法来解决问题
例:求s=1+2+3+4+5+6+……+n
本来这个问题我们过去常用循环累加的方法。而这里如要用递归的方法,必须考虑两点:
1) 能否把问题转化成递归形式的描述;
2) 是否有递归结束的边界条件。
设:函数s(n)=1+2+3+…+(n-1)+n
显然递归的两个条件都有了:
1) s(n) =s(n-1)+n
2) s(1)=1
所以源程序为:
int progression(int n){
int res;
if (n=1 )res=1 else res=progression(n-1)+n;
return res;
}
4、递归的应用
中序遍历二叉树
void inorder (BinTree T){
if (T){
inorder(T->lchild);
printf(“%c”,T->data);
inorder(T->rchild);
}
}
现假设树如图(为了讲解方便,树很简单)

@执行第一次调用inorder1,T指向顶结点,T不为空,所以第二次调用inorder2;
@T指向顶结点的左子树结点也就是B,不为空,所以第三次调用inorder3;
@T指向B结点的左子树结点,为空,所以什么都不执行,返回inorder2;
@打印B结点的DATA域值“b”;
@第四次调用inorder4,去访问B子树的右结点
@T指向B结点的右子树结点,为空,所以什么都不执行,返回inorder2;
@返回inorder1;
@打印A结点的DATA域值“a”;
@第五次调用inorder5,去访问A子树的右结点;
@T指向A结点的右子树结点,为空,所以什么都不执行,返回inorder1;
@inorder1执行完毕,返回。

‘叁’ 递归算法学习难题

一个递归函数就是一个决策过程。
学习递归,关键是掌握分治的思想,就是说我对于一个大的问题,我发现解决他可以分成很多个小步骤,而这些小步骤惊人的相似,于是我就只要写出其中一个小步骤,然后重复利用就好了。
比如说,我面临一个地图,这个地图里有很多的二叉路口,我要走到目的地,就可以看作两个步骤,一个是我想想该走哪个岔路,一个是走上这个岔路口走到另外一个岔路口。我发现这两步操作写成函数是可以直接利用,有相当强的循环性,于是果断的就写成递归了。
所以说,你看递归函数,最关键是要理解每一步他在干什么,他是怎样进行循环操作的。写程序并不是脱离实际的,往往是你现实生活中的决策方式,用代码的形式表现出来,叫计算机按你说的去做而已,所以不用太紧张,
关于回溯,参见http://..com/question/204062355.html。

‘肆’ 递归算法的介绍

递归算法是把问题转化为规模缩小了的同类问题的子问题。然后递归调用函数(或过程)来表示问题的解。一个过程(或函数)直接或间接调用自己本身,这种过程(或函数)叫递归过程(或函数).

‘伍’ 递归法的介绍

递归法是设计和描述算法的一种有力的工具,由于它在复杂算法的描述中被经常采用,为此在进一步介绍其他算法设计方法之前先讨论它。

‘陆’ 请教高人 递归算法编写思路技巧

一个子程序(过程或函数)的定义中又直接或间接地调用该子程序本身,称为递归。递归是一种非常有用的程序设计方法。用递归算法编写的程序结构清晰,具有很好的可读性。递归算法的基本思想是:把规模大的、较难解决的问题变成规模较小的、易解决的同一问题。规模较小的问题又变成规模更小的问题,并且小到一定程度可以直接得出它的解,从而得到原来问题的解。
利用递归算法解题,首先要对问题的以下三个方面进行分析:
一、决定问题规模的参数。需要用递归算法解决的问题,其规模通常都是比较大的,在问题中决定规模大小(或问题复杂程度)的量有哪些?把它们找出来。
二、问题的边界条件及边界值。在什么情况下可以直接得出问题的解?这就是问题的边界条件及边界值。
三、解决问题的通式。把规模大的、较难解决的问题变成规模较小、易解决的同一问题,需要通过哪些步骤或等式来实现?这是解决递归问题的难点。把这些步骤或等式确定下来。
把以上三个方面分析好之后,就可以在子程序中定义递归调用。其一般格式为:
if 边界条件 1 成立 then
赋予边界值 1
【 elseif 边界条件 2 成立 then
赋予边界值 2
┇ 】
else
调用解决问题的通式
endif
例 1 : 计算勒让德多项式的值

x 、 n 由键盘输入。
分析: 当 n = 0 或 n = 1 时,多项式的值都可以直接求出来,只是当 n > 1 时,才使问题变得复杂,决定问题复杂程度的参数是 n 。根据题目提供的已知条件,我们也很容易发现,问题的边界条件及边界值有两个,分别是:当 n = 0 时 P n (x) = 1 和当 n = 1 时 P n (x) = x 。解决问题的通式是:
P n (x) = ((2n - 1)P n - 1 (x) - (n - 1)P n - 2 (x)) / n 。
接下来按照上面介绍的一般格式定义递归子程序。
function Pnx(n as integer)
if n = 0 then
Pnx = 1
elseif n = 1 then
Pnx = x
else
Pnx = ((2*n - 1)*Pnx(n - 1) - (n - 1)*Pnx(n - 2)) / n
endif
end function
例 2 : Hanoi 塔问题:传说印度教的主神梵天创造世界时,在印度北部佛教圣地贝拿勒斯圣庙里,安放了一块黄铜板,板上插着三根宝石针,在其中一根宝石针上,自下而上地放着由大到小的 64 个金盘。这就是所谓的梵塔( Hanoi ),如图。梵天要求僧侣们坚持不渝地按下面的规则把 64 个盘子移到另一根针上:

(1) 一次只能移一个盘子;
(2) 盘子只许在三根针上存放;
(3) 永远不许大盘压小盘。
梵天宣称,当把他创造世界之时所安放的 64 个盘子全部移到另一根针上时,世界将在一声霹雳声中毁灭。那时,他的虔诚的信徒都可以升天。
要求设计一个程序输出盘子的移动过程。
分析: 为了使问题更具有普遍性,设共有 n 个金盘,并且将金盘由小到大依次编号为 1 , 2 ,…, n 。要把放在 s(source) 针上的 n 个金盘移到目的针 o(objective) 上,当只有一个金盘,即 n = 1 时,问题是比较简单的,只要将编号为 1 的金盘从 s 针上直接移至 o 针上即可。可定义过程 move(s,1,o) 来实现。只是当 n>1 时,才使问题变得复杂。决定问题规模的参数是金盘的个数 n ;问题的边界条件及边界值是:当 n = 1 时, move(s,1,o) 。
当金盘不止一个时,可以把最上面的 n - 1 个金盘看作一个整体。这样 n 个金盘就分成了两个部分:上面 n - 1 个金盘和最下面的编号为 n 的金盘。移动金盘的问题就可以分成下面三个子问题(三个步骤):
(1) 借助 o 针,将 n - 1 个金盘(依照上述法则)从 s 针移至 i(indirect) 针上;
(2) 将编号为 n 的金盘直接从 s 针移至 o 针上;
(3) 借助 s 针,将 i 针上的 n - 1 个金盘(依照上述法则)移至 o 针上。如图

其中第二步只移动一个金盘,很容易解决。第一、第三步虽然不能直接解决,但我们已经把移动 n 个金盘的问题变成了移动 n - 1 个金盘的问题,问题的规模变小了。如果再把第一、第三步分别分成类似的三个子问题,移动 n - 1 个金盘的问题还可以变成移动 n - 2 个金盘的问题,同样可变成移动 n - 3 ,…, 1 个金盘的问题,从而将整个问题加以解决。
这三个步骤就是解决问题的通式,可以以过程的形式把它们定义下来:
hanoi(n - 1,s,o,i)
move(s,n,o)
hanoi(n - 1,i,s,o)
参考程序如下:
declare sub hanoi(n,s,i,o)
declare sub move(s,n,o)
input "How many disks?",n
s = 1
i = 2
o = 3
call hanoi(n,s,i,o)
end
sub hanoi(n,s,i,o)
rem 递归子程序
if n = 1 then
call move(s,1,o)
else
call hanoi(n - 1,s,o,i)
call move(s,n,o)
call hanoi(n - 1,i,s,o)
endif
end sub
sub move(s,n,o)
print "move disk";n;
print "from";s;"to";o
end sub

‘柒’ 用递归算法解决问题

递归函数通常用来解决结构自相似的问题。所谓结构自相似,是指构成原问题的子问题与原问题在结构上相似,可以用类似的方法解决。具体地,整个问题的解决,可以分为两部分:第一部分是一些特殊情况,有直接的解法;第二部分与原问题相似,但比原问题的规模小。实际上,递归是把一个不能或不好解决的大问题转化为一个或几个小问题,再把这些小问题进一步分解成更小的问题,直至每个小问题都可以直接解决。因此,递归有两个基本要素:
(1)边界条件:确定递归到何时终止,也称为递归出口。
(2)递归模式:大问题是如何分解为小问题的,也称为递归体。递归函数只有具备了这两个要素,才能在有限次计算后得出结果。
递归就是某个函数直接或间接地调用了自身,这种调用方式叫做递归调用。说白了,还是函数调用。既然是函数调用,那么就有一个雷打不动的原则:所有被调用的函数都将创建一个副本,各自为调用者服务,而不受其他函数的影响。

‘捌’ 递归算法和栈有什么关系栈又是怎样运用的

递归算法和栈都有后进先出这个性质,基本上能用递归完成的算法都可以用栈完成,都是运用后进先出这个性质的
用栈之前首先你要想明白你需要使用“后进先出”干什么,然后才可编写算法,使用中往往是先把数据都压入栈中,然后使用使取出便可,
像表达式求解就是典型的运用栈的例子,可以去看看,会对栈的理解印象深刻些
# include <stdio.h>
# define origial 100
# define add 10
typedef struct
{
int *base;
int *top;
int stack;
}opno;
typedef struct
{
char *base;
char *top;
int stack;
}optr;
void initstacka(opno *a)
{
a->base=(int *)malloc(sizeof(int)*origial);
a->top=a->base;
a->stack=origial;
}
void initstackb(optr *b)
{
b->base=(char *)malloc(sizeof(char)*origial);
b->top=b->base;
b->stack=origial;
*b->top++='#';
}
void pusha(opno *a,int b)
{
if(a->top-a->base>=a->stack)
{
a->base=(int *)realloc(a->base,sizeof(int)*(a->stack+add));
a->top=a->base+a->stack;
a->stack+=add;
}
*a->top++=b;
}
void pushb(optr *b,char c)
{
if(b->top-b->base>=b->stack)
{
b->base=(char *)realloc(b->base,sizeof(char)*(b->stack+add));
b->top=b->base+b->stack;
b->stack+=add;
}
*b->top++=c;
}
int determine(char c)
{
if(c>='0'&&c<='9')
return(1);
else
return(0);
}
char gettopb(optr *b)
{
char a;
a=*(b->top-1);
return(a);
}
char shuzu(int i,int j)
{
char a[7][7]={{'>','>','<','<','<','>','>'},{'>','>','<','<','<','>','>'},{'>','>','>','>','<','>','>'},{'>','>','>','>','<','>','>'},{'<','<','<','<','<','=','0'},{'>','>','>','>','0','>','>'},{'<','<','<','<','<','0','='}};
return(a[i][j]);
}
char precede(char b,char a)
{
int i,j;
char s;
switch(b)
{
case '+':i=0;
break;
case '-':i=1;
break;
case '*':i=2;
break;
case '/':i=3;
break;
case '(':i=4;
break;
case ')':i=5;
break;
case '#':i=6;
break;
}
switch(a)
{
case '+':j=0;
break;
case '-':j=1;
break;
case '*':j=2;
break;
case '/':j=3;
break;
case '(':j=4;
break;
case ')':j=5;
break;
case '#':j=6;
break;
}
s=shuzu(i,j);
return(s);
}
void popb(optr *a,char *b)
{
*b=*--a->top;
}
void popa(opno *a,int *b)
{
*b=*--a->top;
}
int count(int a,int b,char c)
{
int sum=0;
switch(c)
{
case '+':sum=a+b;
break;
case '-':sum=a-b;
break;
case '*':sum=a*b;
break;
case '/':sum=a/b;
break;
}
return(sum);
}
int empty(optr *a)
{
if(a->top==a->base)
return(1);
else
return(0);
}
void main()
{
opno *a;
optr *b;
char c;
char d[50];
int i=0,j=0,k,sum=0,p,o,r,w;
int y[3];
a=(opno *)malloc(sizeof(opno));
b=(optr *)malloc(sizeof(optr));
initstacka(a);
initstackb(b);
printf("请输入表达式!\n");
scanf("%s",d);
while(d[i]!='#'&&d[i]!='\0')
if(determine(d[i]))
{
sum=0;
y[j]=d[i]-'0';
while(determine(d[i+1]))
{
i=i+1;
y[++j]=d[i]-'0';
}
for(k=0;k<=j;k++)
sum=sum*10+y[k];
if(sum!=0)
pusha(a,sum);
else
pusha(a,y[0]);
j=0;
for(k=0;k<3;k++)
y[k]=0;
i=i+1;
}
else
{
switch(precede(gettopb(b),d[i]))
{
case '>':popb(b,&c);
popa(a,&p);
popa(a,&o);
r=count(o,p,c);
pusha(a,r);
break;
case '=':popb(b,&c);
i++;
break;
case '<':pushb(b,d[i]);
i++;
break;
}
}
popb(b,&c);
while(c!='#')
{
popa(a,&o);
popa(a,&p);
r=count(o,p,c);
pusha(a,r);
popb(b,&c);
}
popa(a,&w);
printf("%d",w);
}
这就是运用栈写得表达式求值

‘玖’ 什么是递归算法

递归做为一种算法在程序设计语言中广泛应用.是指函数/过程/子程序在运行过程序中直接或间接调用自身而产生的重入现像.

程序调用自身的编程技巧称为递归( recursion)。
一个过程或函数在其定义或说明中又直接或间接调用自身的一种方法,它通常把一个大型复杂的问题层层转化为一个与原问题相似的规模较小的问题来求解,递归策略只需少量的程序就可描述出解题过程所需要的多次重复计算,大大地减少了程序的代码量。递归的能力在于用有限的语句来定义对象的无限集合。用递归思想写出的程序往往十分简洁易懂。
一般来说,递归需要有边界条件、递归前进段和递归返回段。当边界条件不满足时,递归前进;当边界条件满足时,递归返回。
注意:
(1) 递归就是在过程或函数里调用自身;
(2) 在使用递增归策略时,必须有一个明确的递归结束条件,称为递归出口,否则将无限进行下去(死锁)。

递归算法一般用于解决三类问题:
(1)数据的定义是按递归定义的。(Fibonacci函数)
(2)问题解法按递归算法实现。(回溯)
(3)数据的结构形式是按递归定义的。(树的遍历,图的搜索)

递归的缺点:
递归算法解题的运行效率较低。在递归调用的过程当中系统为每一层的返回点、局部量等开辟了栈来存储。递归次数过多容易造成栈溢出等。

‘拾’ 怎们理解递归算法

先不要往里想,越想越乱,先想好递归结束(最终返回)的条件,然后通过调用自己每次都将问题简化,这样说问题可能比较抽象,你看看数据结构书中关于树的部分,那里递归比较多,而且很多递归都不难,比如前序 中序 后序遍历,找些课本上的程序,用一些简单的树为例子一步步走一下,相信你会更清晰的

阅读全文

与递归算法在桥梁中的应用论文相关的资料

热点内容
位域结构体编译树形描述 浏览:652
宏基手机如何装安卓系统 浏览:743
linuxcp命令实现 浏览:668
单片机热释红外报警器 浏览:661
单片机原理及接口技术b卷 浏览:356
php链接正则表达式 浏览:966
安卓版苹果手机怎么转手 浏览:103
安卓怎么修改app的名字 浏览:139
域名服务器可将域名地址 浏览:724
广州服务器机柜怎么卖 浏览:238
转让腾讯云三年服务器 浏览:254
网易云音乐加密怎么处理 浏览:389
编译小视频软件 浏览:597
盒马app买东西怎么送 浏览:121
编译原理国产 浏览:694
在线用pdf转word 浏览:426
咪咕app怎么发表文章 浏览:209
phpsftp上传 浏览:936
php可以干嘛 浏览:879
梁箍筋加密区需要满绑扎吗 浏览:331