递归二叉树遍历代码转到无穷大

时间:2016-01-10 19:46:03

标签: c++ recursion binary-search-tree tree-traversal

我正在尝试遍历使用键盘输入数据构建的二叉树。数据已成功插入二叉树。我有一个switch语句,其中' case 2'应该分别使用递归遍历(和打印)具有Inorder,Preorder和Postorder遍历算法的二叉树。但是当情况2'如果被调用,则只有第一个关于Inorder遍历应该打印的数据被打印在屏幕上;它也被打印多次(无限),我需要停止编译操作。如果有人帮我解决这个问题,我会非常高兴。

(RootPtr是全局定义的二叉树的顶级0节点; GetNode基本上是类型TreePtr指针的初始化函数(使用malloc)。)

提前谢谢大家。

这是结构定义;

  typedef struct treeItem
{
    int data;
    struct treeItem *left;
    struct treeItem *right;

}Tree , *TreePtr;

这三个是分别调用的遍历函数;

void inorder (TreePtr TemPtr)
{

    while(TemPtr != NULL)
    {
        inorder((*TemPtr).left);
        printf(" %d ", (*TemPtr).data);
        inorder((*TemPtr).right);
    }
    printf("\n");
}

void preorder (TreePtr TemPtr)
{
    while(TemPtr != NULL)
    {
        printf(" %d ", (*TemPtr).data);
        preorder((*TemPtr).left);
        preorder((*TemPtr).right);
    }
    printf("\n");
}

void postorder (TreePtr TemPtr)
{
    while(TemPtr != NULL)
    {
        postorder((*TemPtr).left);
        postorder((*TemPtr).right);
        printf(" %d", (*TemPtr).data);
    }
    printf("\n");
}

这是一个相关的案例' switch语句;

  case 2:
            TreePtr LocPtr;
            GetNode(&LocPtr);
            LocPtr = RootPtr;

            printf("\n");
            printf("Inorder traversal:");
            inorder(LocPtr);
            printf("Preorder traversal:");
            preorder(LocPtr);
            printf("Postorder traversal:");
            postorder(LocPtr);
            printf("\n");

            break;

1 个答案:

答案 0 :(得分:0)

遍历函数中不应该有while循环。递归将在所有节点中进行。

void inorder (TreePtr TemPtr)
{
    if (TemPtr != NULL) {
        inorder((*TemPtr).left);
        printf(" %d ", (*TemPtr).data);
        inorder((*TemPtr).right);
    }

    printf("\n");
}

如果您考虑一下,当您循环迭代时,TemPtr参数不会更改为NULL。因此它会陷入无限循环。

树遍历的解释:

在您的主要case 2中,您使用树的根作为参数调用inorder。然后我们需要遍历树。

inorder(LocPtr);

有序遍历是:

  

转到左边的孩子...访问当前节点...转到右边的孩子

我们在递归函数/方法中需要两件事:一个基本案例和一个递归调用。

在这里,我们的基本案例是if (TemPtr != NULL)。当这个条件是假的时候,我们知道我们已经到了一片叶子。如果TemPtr确实是一片叶子,我们就不会再去它的孩子了(会抛出错误)。

但如果TemPtr不是NULL,则表示我们当前处于有效节点。因此,我们必须遵循有序遍历的定义(如前所述)。

我们访问了左边的孩子:

inorder((*TemPtr).left); // equivalent to inorder(TemPtr->left);

我们访问当前节点:

printf(" %d ", (*TemPtr).data); // equivalent to printf (" %d ", TemPtr->data);

我们拜访了正确的孩子:

inorder((*TemPtr).right); // equivalent to inorder(TemPtr->right);


完成inorder后,inorder的来电者将继续。这个过程一直持续到inorder(LocPtr)结束,此时你将回到主体,你的整个树将被按顺序遍历。

最简单的可视化方法是在一张纸上绘制调用。函数将相互堆叠(底部为main),并在完成后从堆栈中删除。