如何利用栈消除递归编写求函数F(n)=n!的非递归算法实现求解啊?

a214114110 2010-12-21 08:00:50
在线求解..!!
...全文
1162 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
yyfhz 2010-12-23
  • 打赏
  • 举报
回复
老师大概是为了让你们了解OS中是如何对递归函数进行编译的才这么敢的吧,比较的BT :)

==============================================
首先是递归算法
int Calc(int n) {
if (n==1) {
return 1;
} else {
return n*Calc(n-1);
}
}

然后用栈来描写递归算法的参数传递以及结果返回,即用一个全局栈来代表每一次的传入参数,同时去除函数的型参列表。比方说原来的Calc(n)就可以变成
STACK param;
param.push(n);
int Calc() {
int i= param.pop(); //获得传入参数
if (i==1) {
return 1;
) else {
param.push(i-1);
return i*calc();
}
}

//再利用一个全局栈来返回Calc()的结果,并将Calc()改写为无参数无返回值的方法
STACK param;
STACK result;
param.push(n);
void Calc() {
int i= param.pop(); //获得传入参数
if (i==1) {
result.push(1);
) else {
param.push(i-1);
Calc();
int i_1 = result.pop(); //获取(i-1)!的内容
result.add(i*i_1);
}
}

//再将这个方法完全打散,其结束标志就是栈param为空
STACK param;
STACK result;
param.push(n);
void Calc() {
int i, value;
start:
i= param.popup();
if (i==1) {
result.push(1);
} else {
param.push(i); //保留本次操作的参数
param.push(i-1); //下一次操作的参数
go to start;
}
end:
//计算完毕了,依次返回结果
//获取当前参数
i= param.popup();
value = result.popup(); //去除Calc(i-1)的值
result.push(value*i);
if (!param.isEmpty()) {
go to end;
}
//最后的结果就是result.popup()
}

最后将参数和返回值挂回到Calc方法中,将2个Stack放在函数体内进行定义和赋值,并采用结构化形式改写go to 语句就可以了。(注意:由于栈result中最多只有1个值,所以可以用普通整型数来定义result,不必使用栈)
hw_henry2008 2010-12-23
  • 打赏
  • 举报
回复
typedef struct M{
char info[MAX];
struct M *lchild,*rchild;
}TreeNode,* PNode;

char replay[5],answer[5];
PNode root;
int size = sizeof(TreeNode);
下面的函数完成构建如下树的功能:
你猜的是哺乳动物吗?
比猫大吗? 生活在水里吗?
袋鼠 老鼠 鲑鱼 鸟


void Init()
{ //建立根结点:你是哺乳动物吗?
strcpy(replay,"yes");
root=(TreeNode*)malloc(size);
strcpy(root->info,"你猜的是哺乳动物吗?");
//建立左子树:比猫大吗?
root->lchild=(TreeNode*)malloc(size);
strcpy(root->lchild->info,"比猫大吗?");
//左:袋鼠
root->lchild->lchild=(TreeNode*)malloc(size);
strcpy(root->lchild->lchild->info,"袋鼠");
root->lchild->lchild->lchild = root->lchild->lchild->rchild = NULL;
//右:老鼠
root->lchild->rchild=(TreeNode*)malloc(size);
strcpy(root->lchild->rchild->info,"老鼠");
root->lchild->rchild->lchild = root->lchild->rchild->rchild = NULL;
//建立右子树:生活在水里吗?
root->rchild=(TreeNode*)malloc(size);
strcpy(root->rchild->info,"生活在水里吗?");
//左:鲟鱼
root->rchild->lchild=(TreeNode*)malloc(size);
strcpy(root->rchild->lchild->info,"鲑鱼");
root->rchild->lchild->lchild = root->rchild->lchild->rchild = NULL;
//右:知更鸟
root->rchild->rchild=(TreeNode*)malloc(size);
strcpy(root->rchild->rchild->info,"鸟");
root->rchild->rchild->lchild = root->rchild->rchild->rchild = NULL;
}

void Change(char str[])
{
int i=0;
while(str[i]!='\0'){
str[i++]=tolower(str[i]);
}
}

void Ask()
{
int flag = 0;
printf("还要再玩一次吗?\n");
while(!flag){
gets(answer);
Change(answer);
if(!strcmp(answer,"yes")||!strcmp(answer,"y")){
flag = 1;
strcpy(replay,"yes");
}
else if(!strcmp(answer,"no")||!strcmp(answer,"n")){
flag = 1;
strcpy(replay,"no");
}
else {
printf("再次输入答案(Y/N):\n");
}
}
}

//当猜错时,加入新的动物和新回答
void Learn(PNode p)
{
char s1[MAX],s2[MAX],s[5],temp[MAX];
PNode p1,p2;
int flag = 0;
printf("我认输了,那是什么呢?\n");
gets(s1);//读入答案
printf("请输入一个可以区分开%s和%s的问题:\n",s1,p->info);//询问用户
gets(s2);
printf("对于%s,你的回答是(Y/N):\n",s1);
gets(s);
//把新问题作为当前结点值,为两个动物建立2个新结点作为它的左子树
strcpy(temp,p->info);
strcpy(p->info,s2);
p1 = (TreeNode*)malloc(size);
strcpy(p1->info,temp);
p1->lchild = p1->rchild = NULL;
p2 = (TreeNode*)malloc(size);
strcpy(p2->info,s1);
p2->lchild = p2->rchild = NULL;
while(!flag){
Change(s);
if(!strcmp(s,"yes")||!strcmp(s,"y")){
p->lchild=p2;
p->rchild=p1;
flag = 1;
}
else if(!strcmp(answer,"no")||!strcmp(answer,"n")){
p->lchild=p1;
p->rchild=p2;
flag = 1;
}
else {
printf("再次输入答案(Y/N):\n");
}
}
printf("好的,我记住了!\n");
}
void Request()
{
int flag;
PNode p;
printf("游戏开始:\n");
p=root;
while(p!=NULL)
{
flag = 0;
if(p->lchild!=NULL){printf("%s\n",p->info);}
else{printf("它是%s吗?\n",p->info);}
while(!flag){
gets(answer);
Change(answer);
if(!strcmp(answer,"yes")||!strcmp(answer,"y")){
if(p->lchild==NULL)printf("猜对了!\n");
p=p->lchild;
flag = 1;
}
else if(!strcmp(answer,"no")||!strcmp(answer,"n")){
if(p->lchild==NULL){Learn(p);p=NULL;}
else p=p->rchild;
flag = 1;
}
else {
printf("再次输入答案(Y/N):\n");
}
}
}
Ask();
}
int main()
{
Init();
while(!strcmp(replay,"yes"))

{
Request();
}
return 0;
}
SomethingWrong 2010-12-21
  • 打赏
  • 举报
回复
啥意思?

做一个类似递归的东西
把从n到1挨个压栈,再挨个弹出来都乘起来?

有点浪费吧。
a214114110 2010-12-21
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 somethingwrong 的回复:]
啥意思?栈消除递归?回溯吗?用循环做阶乘不行吗
[/Quote]

不能用递归啊.循环也不行啊..

要用栈来消除递归...即非递归.!
SomethingWrong 2010-12-21
  • 打赏
  • 举报
回复
啥意思?栈消除递归?回溯吗?用循环做阶乘不行吗
a214114110 2010-12-21
  • 打赏
  • 举报
回复
高手啊高手啊..! 出来帮帮我啊..!!
a214114110 2010-12-21
  • 打赏
  • 举报
回复
怎么高手不在呢..苦苦的等待啊.

33,008

社区成员

发帖
与我相关
我的任务
社区描述
数据结构与算法相关内容讨论专区
社区管理员
  • 数据结构与算法社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧