【数据结构】栈与递归例题:Ackerman函数

题目:已知Ackerman函数的定义如下:

akm= \begin{cases} n+1 & m=0\\ akm(m-1,1) & m\ne0,n=0\\ akm(m-1,akm(m,n-1)) & m\ne0,n\ne0\\ \end{cases}

 (1)写出递归算法;

(2)写出非递归算法;

(3)根据递归算法,画出求akm(2,1)时栈的变化过程。


部分概念

递归函数:一个直接调用自己或通过一系列的调用语句间接地调用自己的函数,称作递归函数。

递归工作栈:整个递归函数运行期间使用的数据存储区,每一层递归信息构成一个“工作记录”。当前执行层的工作记录必为递归工作栈栈顶,此记录称为“活动记录”,指示该记录的栈顶指针称为”当前环境指针“


递归直接按函数定义,if else语句分类执行。

递归算法如下:

int akm(int m, int n)
{
 if (m==0) akm=n+1;
 else if (n==0) akm=akm(m-1,1);
 else{
 	g=akm(m,n-1);
 	akm=akm(m-1,g);
 }
}//akm

转换为非递归算法时,需要递归工作栈的辅助,利用其“先进后出”的特性,逐层计算。

观察函数可知,仅m=0时函数不再嵌套,且n也非函数时才可解出确定值。可用栈顶指针指示层数,工作记录记录该层数下的m,n值,此处的m,n值仅为akm函数内的,上一层被影响的m值应逐层解套至其位置的时候再改变。以m,n非0为判断依据,由于m=0是停止嵌套的条件,故以m为主循环在外,嵌套以n为主的循环。由m=0出循环后还需检验层数,若非最外层(栈不为空,说明此时n还是函数)则还需继续,处理活动记录并下移当前环境指针,以此为判断依据再套一个循环。注意当栈空且m=0时还需一次计算。

非递归算法如下:

int akm1(int m, int n)
{
 //S[MAX]为附设栈,top为栈顶指针
 top=0;S[top].mval=m;S[top].nval=n;
 do {
 while (S[top].mval){
 	while(S[top].nval){
 		top++;S[top].mval=S[top-1].mval;
 		S[top].nval=S[top-1].nval-1;
	 }
	S[top].mval--;S[top].nval=1;
 }
 if (top>0){
 	top--;
 	S[top].mval--;
 	S{top}.nval=S[top+1].nval+1;
 }
 } while (top!=0||S[top].mval!=0);
 akm1=S[top].nval+1;
}//akm1

当计算akm(2,1)时,各参数变化如下

topS.mavlS.val执行操作
021

top=0;S[top].mval=m;S[top].nval=n;

1

20

top++;S[top].mval=S[top-1].mval;

S[top].nval=S[top-1].nval-1;

111S[top].mval--;S[top].nval=1;
210

top++;S[top].mval=S[top-1].mval;

S[top].nval=S[top-1].nval-1;

201S[top].mval--;S[top].nval=1;
102

top--;S[top].mval--;

S{top}.nval=S[top+1].nval+1;

013

top--;S[top].mval--;

S{top}.nval=S[top+1].nval+1;

112

top++;S[top].mval=S[top-1].mval;

S[top].nval=S[top-1].nval-1;

211

top++;S[top].mval=S[top-1].mval;

S[top].nval=S[top-1].nval-1;

310

top++;S[top].mval=S[top-1].mval;

S[top].nval=S[top-1].nval-1;

301S[top].mval--;S[top].nval=1;
202

top--;S[top].mval--;

S{top}.nval=S[top+1].nval+1;

103

top--;S[top].mval--;

S{top}.nval=S[top+1].nval+1;

004

top--;S[top].mval--;

S{top}.nval=S[top+1].nval+1;

akm1=5akm1=S[top].nval+1;

习题代码均来源于清华大学出版社《数据结构题集:C语言版》,仅作为自己的思路记录

  • 1
    点赞
  • 31
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值