将递归二叉树遍历转换为迭代
我被要求编写迭代版本,但我编写了递归版本,即
void inorderTraverse(BinaryTree root)
{
if(root==NULL)
printf("%d",root->id);
else
{
inorderTraverse(root->left);
printf("%d",root->id);
inorderTraverse(root->right);
}
}
我不是在寻找代码,我想了解这是如何完成的。如果这只是最后一次递归调用,我会这样做
void inorderTraverse(BinaryTree root)
{
while(root!=NULL)
{
printf("%d",root->id);
root=root->right;
}
}
但是当有两个递归调用时如何转换为迭代程序?
这里是类型定义。
struct element{
struct element* parent;
int id;
char* name;
struct element* left;
struct element* right;
};
typedef element* BinaryTree;
这就是我的想法,我的方向正确吗?
temp=root;
while(1)
{
while(temp!=NULL)
{
push(s,temp);
temp=temp->left;
continue;
}
temp=pop(s);
if(temp==NULL)
return;
printf("%d\t",temp->data);
temp=temp->right;
}
I was asked to write the iterative version, but I wrote the recursive version i.e.
void inorderTraverse(BinaryTree root)
{
if(root==NULL)
printf("%d",root->id);
else
{
inorderTraverse(root->left);
printf("%d",root->id);
inorderTraverse(root->right);
}
}
I'm not looking for the code, I want to understand how this can be done. Had it been just the last recursive call, I would have done
void inorderTraverse(BinaryTree root)
{
while(root!=NULL)
{
printf("%d",root->id);
root=root->right;
}
}
But how do I convert to an iterative program when there are two recursive calls?
Here are the type definitions.
struct element{
struct element* parent;
int id;
char* name;
struct element* left;
struct element* right;
};
typedef element* BinaryTree;
This is what I thought of, am I on the right track?
temp=root;
while(1)
{
while(temp!=NULL)
{
push(s,temp);
temp=temp->left;
continue;
}
temp=pop(s);
if(temp==NULL)
return;
printf("%d\t",temp->data);
temp=temp->right;
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
您遇到的问题是您需要“记住”您迭代的最后一个位置。
进行递归时,程序内部使用“堆栈”来记住要返回到哪里。
但在进行迭代时,却不然。
虽然……这给了你一个想法吗?
The problem you're seeing is that you need to "remember" the last place you were iterating at.
When doing recursion, the program internally uses "the stack" to remember where to go back to.
But when doing iteration, it doesn't.
Although... does that give you an idea?
我想不出一种真正优雅的方式来临时迭代地完成此操作。
一种可能性可能是使用“标记算法”,在该算法中,您从所有节点“未标记”开始,并在处理节点时对其进行“标记”。标记可以添加到对象模型中或保存在单独的实体中。
伪代码:
I can't think of a really elegant way to do this iteratively off-hand.
One possibility might be using a 'mark algorithm', where you start out with all nodes 'unmarked' and 'mark' nodes as they're handled. The markers can be added to the object model or kept in a seperate entity.
Pseudocode:
我想当然地认为,从父节点向下迭代到左节点不是问题。问题是知道从一个节点上升到父节点时该怎么做:应该选择正确的子节点还是应该再上升一个父节点?
以下技巧将帮助您:
在向上移动之前记住当前节点。然后向上走。现在你可以比较: 是否已经在左边的节点了: 那么就取右边的节点。否则再上一层父节点。
为此,您只需要一个参考/指针。
I take it for granted, that iterating down from the parent nodes to the left nodes is not a problem. The problem is to know what to do when going up from one node to the parent: should you take the right child node or should you go up one more parent?
The following trick will help you:
Before going upwards remember the current node. Then go upwards. Now you can compare: Have you been in the left node: Then take the right node. Otherwise go up one more parent node.
You need only one reference/pointer for this.
有一种将递归遍历转换为迭代器的通用方法,即使用连接多个迭代器提供者的惰性迭代器(返回迭代器的 lambda 表达式)。请参阅我的将递归遍历转换为迭代器。
There is a general way of converting recursive traversal to iterator by using a lazy iterator which concatenates multiple iterator suppliers (lambda expression which returns an iterator). See my Converting Recursive Traversal to Iterator.