我正在尝试遍历使用键盘输入数据构建的二叉树。数据已成功插入二叉树。我有一个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;
答案 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
),并在完成后从堆栈中删除。