将递归二叉树遍历转换为迭代

时间:2011-09-25 19:30:34

标签: c recursion iteration binary-tree imperative-programming

我被要求编写迭代版本,但我编写了递归版本,即

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;
}

4 个答案:

答案 0 :(得分:3)

您遇到的问题是您需要“记住”您正在迭代的最后一个地方
在进行递归时,程序在内部使用“堆栈”来记住返回的位置 但是在进行迭代时,却没有。

虽然......这会给你一个想法吗?

答案 1 :(得分:0)

我无法想到一个真正优雅的方式来迭代地执行此操作。

一种可能性可能是使用“标记算法”,您可以在处理完所有节点的“未标记”和“标记”节点时开始使用。标记可以添加到对象模型中,也可以保存在单独的实体中。

伪代码:

for (BinaryTree currentNode = leftmostNode(root); currentNode != null; currentNode = nextNode(currentNode)):
  print currentNode;
  currentNode.seen = true;

sub nextNode(BinaryTree node):
  if (!node.left.seen):
    return leftmostNode(node.left)
  else if (!node.seen)
    return node
  else if (!node.right.seen)
    return leftmostNode(node.right)
  else 
    return nextUnseenParent(node)

sub leftmostNode(BinaryTree node):
  while (node.left != null)
    node = node.left
  return node;

sub nextUnseenParent(BinaryTree node):
  while (node.parent.seen)
    node = node.parent
  return node.parent

答案 2 :(得分:0)

我认为理所当然,从父节点迭代到左边节点不是问题。问题是要知道当从一个节点上升到父节点时该怎么做:你应该选择正确的子节点还是再增加一个父节点?

以下技巧可以帮助您:

在向上之前记住当前节点。然后向上走。现在您可以比较:您是否在左侧节点中:然后选择正确的节点。否则再上一个父节点。

您只需要一个参考/指针。

答案 3 :(得分:0)

通过使用连接多个迭代器供应商的lazy迭代器(lambda表达式返回迭代器),有一种将递归遍历转换为迭代器的一般方法。查看我的Converting Recursive Traversal to Iterator

相关问题