消递归(recursion)的一种方式
来源:互联网 发布:echo 输出数组 编辑:程序博客网 时间:2024/04/29 22:20
注:本文的例子开发的环境为WINXP,VC 6.0
递归由于其函数栈嵌套的层数未定,在很多情况下,可能出现函数栈溢出,引起程序的崩溃。所以在某些情况下,认为的消除递归是非常有必要的。总的来说递归的消除的方式有2大类,一种为利用无限循环来消除,另一种是自己模拟栈(从heap中分配空间)来保存中间变量,来达到消递归的目的。在不同种类的消递归方式中,亦有自己不同的实现方式,本文利用模拟栈的方法来具体实现,兼以例子来说明。
我们现在以计算两个整数(int)n与m的最大公约数(dcg)为例来说明。
1) 如果利用递归方式,我们的程序可能如下(为了程序清晰):
/*dcg: recursion*/
int dcg_recursion(int n,int m)
{
if ( n < m )
{
return dcg_recursion(m,n);
}
if ( 0 == m)
{
return n;
}
else
{
return dcg_recursion(m,n%m);
}
}
此种方式中,递归的次数是未定(不可控),完全基于n与m两个数;
2) 利用模拟栈的方式,我们程序如下:
//定义一个栈(或叫帧frame),用于保存临时数据
/*dcg: no recursion*/
typedef struct tagSt_DCG St_DCG;
struct tagSt_DCG
{
St_DCG* pre;
int n;
int m;
int l;
};
//no recursion入口
#define MC_DCG_NO_RECURSION(pstDcg,n,m,l) /
{/
pstDcgTemp = (St_DCG*)malloc(sizeof(St_DCG));/
memset(pstDcgTemp,0,sizeof(St_DCG));/
pstDcgTemp->n = n;/
pstDcgTemp->m = m;/
if(pstDcg)/
{/
pstDcgTemp->pre = pstDcg;/
}/
pstDcg = pstDcgTemp;/
pstDcgTemp = NULL;/
goto NO_RECURSION_START;/
L_##l:/
;/
}
//no recursion出口
#define MC_RETURN(ra)/
{/
pstDcgTemp = pstDcg;/
if(!pstDcg){return ra;}/
pstDcg = ((St_DCG*)pstDcg)->pre;/
free(pstDcgTemp);/
if(pstDcg)/
{/
goto NO_RECURSION_RETURN;/
}/
else/
{/
return ra;/
}/
}
#define LBL(l) case l: goto L_##l;
int dcg_no_recursion(int n, int m)
{
St_DCG* pstDcg = NULL;
St_DCG* pstDcgTemp = NULL;
int mid = 0;
NO_RECURSION_START:
int ra = n;
if(0 == m)
{
MC_RETURN(ra);
}
if (n < m)
{
mid=n;n=m;m=mid;
MC_DCG_NO_RECURSION(pstDcg,n,m,1)
}
else
{
n = n%m;
MC_DCG_NO_RECURSION(pstDcg,m,n,2)
}
NO_RECURSION_RETURN:
switch(pstDcg->l)
{
LBL(1)LBL(2)
default:
return ra;
}
}
主要思想是,在本来递归调用自身函数的地方去保存一些数据(基本是为了回复现场用),然后不出自身函数,goto到函数的基本起始位置,这样就减少了调用函数时候的压栈与出栈的开销;在函数返回的地方调用模拟返回,判断是否已是模拟栈的最后一项,如是则出函数,返回最后结果,如否则利用goto到上一模拟栈终止的地方,继续执行。
- 消递归(recursion)的一种方式
- 递归(recursion)
- 递归(Recursion)
- 递归(recursion)
- 关于递归(recursion)的总结
- 递归算法(recursion algorithm)
- 阶乘的尾递归(Tail Recursion)写法(C++)
- recursion-insert-sort( 插入排序的递归实现 )
- C++ Recursion(递归)的运用 及 例子
- 递归(Recursion)的两种优化方法
- 递归(Recursion)的两种优化方法
- 递归与尾递归(Tail Recursion)
- 递归 recursion
- Recursion--递归
- 尾递归(tail recursion) 的简单使用
- 递归思想的原理与应用 Recursion
- Lisp.使用递归(Using Recursion)
- 迭代(Iteration)与递归(Recursion)
- 软件as一种商品
- 如何关闭dd-wrt std 的telnet 和 DNS 端口?
- php点击下载txt文件
- typedef用于函数定义的一个例子
- Microsoft .NET策略及框架概述
- 消递归(recursion)的一种方式
- Now is start live
- 另类妙招--用非常规手段有效删除怪文件
- 关于初学ASP.NET技术的学习顺序问题
- 工作的尊严... (转)
- Can i belive my girlfriend?
- 十字星,影线,光脚阴线阳线
- Windows XP 系统网络应用技巧集锦
- 一女孩写的经典“代码”,程序员该如何应对?