1.Ackerman阿克曼函数定义
定义如下:
2.Ackerman函数实现
2.1递归实现
对三种情况进行判断,进行递归即可
int Akm1(int m,int n)
{
if(m==0)
return n+1;
else if(n==0)
return Akm1(m-1,1);
else
return Akm1(m-1,Akm1(m,n-1));
}
2.2非递归实现
首先定义Akm函数的结构体类型,如下:
#define MaxSize 100
typedef struct
{
int m,n;//保存m,n的值
int flag;//标记是否求出akm(m,n)的值 1:未求出,0:已求出
int sum;//保留akm(m,n)的值
}AkmStack;
这里将栈顶top指针放在外面定义,并将初始值入栈
AkmStack St[MaxSize];
int top=-1;//栈顶指针
top++;//初值进栈
St[top].m=m;
St[top].n=n;
St[top].flag=1;
转化思想:将Akm的递归计算放入循环中,每次计算栈顶的Akm函数
进行入栈或者出栈操作,直到栈中只有一个元素,即为最终结果,退出循环
int Akm2(int m,int n)
{
AkmStack St[MaxSize];
int top=-1;//栈顶指针
top++;//初值进栈
St[top].m=m;
St[top].n=n;
St[top].flag=1;
while(top>-1)
{
if(St[top].flag==1)//如果栈顶为未计算akm,执行三个判断
{
if(St[top].m==0)//m=0,执行1式直接求出sum
{
St[top].sum=St[top].n+1;
St[top].flag=0;//flag置0表示已求出
}
else if(St[top].n==0)//n=0时 将akm(m-1,1)入栈顶,并且标记为未计算(flag=1)
{
top++;
St[top].m=St[top-1].m-1;
St[top].n=1;
St[top].flag=1;
}
else//m,n都不为0 ,将akm(m-1,n)入栈顶,标记为未计算
{
top++;
St[top].m=St[top-1].m;
St[top].n=St[top-1].n-1;
St[top].flag=1;
}
}
else//如果栈顶为已计算出的akm,继续考虑2式和3式
{
if(top>0&&St[top-1].n==0)
//栈顶为已计算出的akm,栈顶下面一个元素akm的n为0
//则栈顶下面一元素的m必为1,此时直接赋值,并标记为已计算,出栈
{
St[top-1].sum=St[top].sum;
St[top-1].flag=0;
top--;
}
else if(top>0)
//栈顶为已计算的akm,栈顶下面一个元素akm为3式
//则三式逗号后akm即为栈顶已计算出的sum,直接赋值给n,出栈
{
St[top-1].m=St[top-1].m-1;
St[top-1].n=St[top].sum;
St[top-1].flag=1;
top--;
}
}
if(top==0&&St[top].flag==0)//栈中只有一个元素且为已计算,退出
break;
}
return St[top].sum;
}