社区
C语言
帖子详情
递归-->非递归
dpdp_2012
2012-10-19 09:40:22
假设不知道程序的功能,单单知道递归函数,怎么把递归函数转化成非递归形式,如:
void hx(node *p)
{
if(p)
{
hx(p->left);
hx(p->right);
printf("%c",p->c);
}
}
...全文
231
9
打赏
收藏
递归-->非递归
假设不知道程序的功能,单单知道递归函数,怎么把递归函数转化成非递归形式,如: void hx(node *p) { if(p) { hx(p->left); hx(p->right); printf("%c",p->c); } }
复制链接
扫一扫
分享
转发到动态
举报
AI
作业
写回复
配置赞助广告
用AI写文章
9 条
回复
切换为时间正序
请发表友善的回复…
发表回复
打赏红包
dpdp_2012
2012-10-19
打赏
举报
回复
5L没明白我的意思,我说后序只是举个例子。
我想要的是从递归函数参数对应压栈这方面考虑得出非递归形式,我想要的是一般规律,就像把数字1转化成字符'1'只要1+'0'即可。懂我意思么
AndyZhang
2012-10-19
打赏
举报
回复
二叉树后序遍历,网上非递归实现一大堆
dpdp_2012
2012-10-19
打赏
举报
回复
//栈,用于标识从左(0)或右(1)返回
果然是需要做这样的标记。
另外我的意思是说,如何从递归函数一步步看压入了哪些参数(对应压入自己设的栈中),有没有规律从这方面着手快速地得出非递归形式
会飞的闪电狮子
2012-10-19
打赏
举报
回复
网上找的一段代码,看了下,没什么问题,但是我没实际去试,贴出来你看下,或者直接去 http://www.cnblogs.com/hicjiajia/archive/2010/08/27/1810055.html
这里我们约定:空的节点用空格表示,按照前序遍历来创建树!
#include <iostream>
using namespace std;
typedef struct node {
char data;
struct node *lchild;
struct node *rchild;
}BiNode,*BiTree;
typedef struct node1{
BiTree data[30]; //默认30个元素 ,这里需要一个辅助堆栈!!!
int top;
}Stack;
void createTree(BiTree &T) //先序递归创建树,这里注意参数的类型,T的类型是 "*&" ,如果是 "**" 代码稍加改动就OK...
{
char ch;
cin.get(ch).get(); //过滤输入流中每次回车产生的回车符
if (ch==' ') T=NULL; //这里首先判断是不是空格,如果是,则为该节点赋NULL
else{
T=(BiTree)malloc(sizeof(BiNode));
T->data=ch;
createTree(T->lchild);
createTree(T->rchild);
}
}
void initstack(Stack *&st)
{
st=(Stack *)malloc(sizeof(Stack));
st->top=-1;
}
bool isempty(Stack *st)
{
return st->top==-1;
}
bool isfull(Stack *st)
{
return st->top==19;
}
void push(Stack *st,BiTree T)
{
if (!isfull(st))
st->data[++st->top]=T; //栈顶指针始终指向堆栈最上面可用的一个元素,因此入栈时候,先要将指针加1,然后再执行入栈操作!
else cout<<"已满"<<endl;
}
BiTree pop(Stack *st)
{
if (!isempty(st)) return st->data[st->top--];
}
BiTree gettop(Stack *st)
{
if (!isempty(st)) return st->data[st->top]; //出栈时,先取出栈顶指针指向的元素,然后再将指针减1,使其指向栈中下一个可用元素!
}
void preOrderNoRe(BiTree T) // 前序遍历
{
Stack *st;
initstack(st);
BiTree p;
p=T;
while (p!=NULL||!isempty(st))
{
while (p!=NULL)
{
cout<<p->data<<" ";
push(st,p);
p=p->lchild;
}
if (!isempty(st))
{
p=pop(st);
p=p->rchild;
}
}
}
void inOrderNoRe(BiTree T) //中序遍历
{
Stack *st;
initstack(st);
BiTree p;
p=T;
while (p!=NULL||!isempty(st))
{
while (p!=NULL)
{
push(st,p);
p=p->lchild;
}
if (!isempty(st))
{
p=pop(st);
cout<<p->data<<" ";
p=p->rchild;
}
}
}
void postOrderNoRe(BiTree T) //后序遍历
{
BiTree p;
Stack *st;
initstack(st);
p=T;
int Tag[20]; //栈,用于标识从左(0)或右(1)返回
while (p!=NULL || !isempty(st))
{
while (p!=NULL)
{
push(st,p);
Tag[st->top]=0;
p=p->lchild;
}
while (!isempty(st)&&Tag[st->top]==1)
{
p=pop(st);
cout<<p->data<<" ";
}
if (!isempty(st))
{
Tag[st->top]=1; //设置标记右子树已经访问
p=gettop(st);
p=p->rchild;
}
else break;
}
}
int main()
{
cout<<"Enter char one by one hicjiajia"<<endl;
BiNode *T;
createTree(T);
cout<<endl;
cout<<"preOrderNoRe: ";preOrderNoRe(T);cout<<endl;
cout<<"inOrderNoRe: ";inOrderNoRe(T);cout<<endl;
cout<<"postOrderNoRe: ";postOrderNoRe(T);cout<<endl;
system("pause");
return 0;
}
会飞的闪电狮子
2012-10-19
打赏
举报
回复
二叉树的后序遍历,
不知道你的结构体怎么定义的,孩子结点有没有指向父节点的指针呢,如果有还可以弄,没有的话改为非递归会有些麻烦。
hu7324829
2012-10-19
打赏
举报
回复
非递归二叉树 一般用一个栈可以完成.
dpdp_2012
2012-10-19
打赏
举报
回复
[Quote=引用 8 楼 的回复:]
http://www.codeproject.com/Articles/418776/How-to-replace-recursive-functions-using-stack-and
[/Quote]
这个讲的很好,我要的就是这个,开始自己写就是这个stage没搞好,还是功底不够。
看了这个,让我想起了以前化学方程号称的万能配平法 (*^_^*)
zhuyf87
2012-10-19
打赏
举报
回复
楼主这个是二叉树的后续遍历。
不过不是所有的递归程序,都可以转换为非递归程序(或者说理论上可以转换,但实际不会那么去做)。
一般是尾递归可以通过循环来去除,从而提高性能。
递归也有递归的好处,程序清晰,并且容易证明正确性。
赵4老师
2012-10-19
打赏
举报
回复
http://www.codeproject.com/Articles/418776/How-to-replace-recursive-functions-using-stack-and
WizardOz
2012-10-19
打赏
举报
回复
首先,应该说不知道算法意义的情况下,按照一定的规律是可以把递归改写成循环的。
但是,其实在不改变算法的情况下,把递归改成非递归是没有实际意义的。
书上说迭代算法和递归算法的优劣,主要是指算法选择上,就比如斐波那契数列,用递归算法会出现很多重复计算,用迭代算法效率很高(也可以用递归的方法来实现迭代算法,效率和迭代差不多)。
如果同样的算法,用一个栈加循环来替代递归,从算法的时间上讲不会有本质改变,相反增加程序复杂程度,使程序难以理解。
自顶向下语法分析方法:消除左
递归
直接左
递归
形如A->Aβ,A∈非终结符,β∈终结符∪非终结符。消除直接左
递归
一般形式: A->Aα1|Aα2|...|Aαm|β1|β2|...|βn 其中,αi(1≤i≤m)不等于ε,βj(1≤j≤n)不以A开头,消除直接左
递归
改写为: A->β1A'|β2A'|...|βnA' A'->α1A'|α2A'|...|αmA'|ε 例如:文法: S->Sa S->b 消除直接左
递归
: S->bS'
非
递归
实现二叉树的前序、中序、后序遍历
二叉树1
非
递归
前序遍历二叉树1.1
递归
前序遍历二叉树 按照教科书上的做法,前序遍历过程如下:先访问根节点,再访问左节点,再访问右节点 另一种访问方式为:按照图中红线的轨迹,第一次遇到的节点即为前序遍历的过程 按照以上两种方法中的任意一种遍历都可以得到如下结果,前序遍历结果 A->B->D->G->H->C->E->I->F 1.2
非
递归
实现前序遍历用栈可以实现二叉树的
非
递归
前序遍
二叉树的遍历(
递归
遍历)
一、什么是二叉树的遍历 所谓遍历(Traversal)是指沿着某条搜索路线,依次对树中每个结点均做一次且仅做一次访问。访问结点所做的操作依赖于具体的应用问 题。 遍历是二叉树上最重要的运算之一,是二叉树上进行其它运算之基础。 二、二叉树遍历分类 遍历:前序遍历(Preorder):根节点----->左节点---->右节点 中序遍历(Inordef): 左节点----->根节点---->右节
【数据结构】二叉树的实现&
递归
遍历(完整代码)
二叉树实现的功能包含以下内容: 1.按要求创建一棵树 2.计算树节点,树叶子节点的个数 3.输出树中第n层的节点个数 4.关于树前序,中序,后序的
递归
遍历 5.树的层序遍历 6.判断树是否为完全二叉树 7.树的前序,中序,后序的
非
递归
遍历 >二叉树的
递归
遍历:直接按遍历顺序
递归
调用 >二叉树的层序遍历可以借用队列结构来实现 >二叉树的
非
递归
遍历可以借用栈结构来实现 > **前序遍历: 根 -- 左 -- 右 > 中序遍历: 左 -- 根 -- 右 > 后序遍历: 左 -- 右 -- 根**
自上而下的语法分析,LL(1)文法(消除左
递归
,提取左因子)
自上而下的语法分析:(推导) 由根节点到叶节点 ※最左推导和最右推导 (每一步替换最左边的非终结符/每一步替换最右边的非终结符),最右推导称为规范推导。最右推导对应于最左规约(规范规约) 例: 文法: S--->AB A--->a|t B---->+CD C--->a D---->a 最右推导: S--->AB---->A+CD--->A+Ca---->A+
C语言
70,024
社区成员
243,263
社区内容
发帖
与我相关
我的任务
C语言
C语言相关问题讨论
复制链接
扫一扫
分享
社区描述
C语言相关问题讨论
社区管理员
加入社区
获取链接或二维码
近7日
近30日
至今
加载中
查看更多榜单
社区公告
暂无公告
试试用AI创作助手写篇文章吧
+ 用AI写文章