yinda_peng 发表于 2023-8-22 18:31:33

求助:为什么没打印?

本帖最后由 yinda_peng 于 2023-8-22 19:47 编辑

代码:

#include <stdio.h>
#include <stdlib.h>

// 定义线索二叉树结点的结构体
typedef struct Node {
    struct Node *lchild;
    int ltag;
    char data;
    int rtag;
    struct Node *rchild;
} Node;

int level = 0;// 当前层数

// 创建线索二叉树
Node* createThreadedBinaryTree() {
    Node *p;
    char c;
    scanf("%c", &c);

    if (c == '^') {// 遇到^符号表示此分支为空
      return NULL;
    }

    p = (Node*)malloc(sizeof(Node));
    p->data = c;
    p->ltag = 0;// 初始化为0
    p->rtag = 0;
    p->lchild = createThreadedBinaryTree();// 递归创建左子树
    p->rchild = createThreadedBinaryTree();// 递归创建右子树

    return p;
}

// 中序遍历线索化二叉树(中序线索化过程)
void inorderThreaded(Node *p, Node **pre) {
    if (p != NULL) {
      inorderThreaded(p->lchild, pre);// 递归线索化左子树

      // 处理当前结点
      if (p->lchild == NULL) {// 左孩子为空,将ltag置为1,指向前驱结点
            p->ltag = 1;
            p->lchild = *pre;
      }
      
      if (*pre != NULL && (*pre)->rchild == NULL) {// 前驱结点的右孩子为空,将rtag置为1,指向后继结点
            (*pre)->rtag = 1;
            (*pre)->rchild = p;
      }

      *pre = p;
      inorderThreaded(p->rchild, pre);// 递归线索化右子树
    }
}

// 打印线索二叉树图示化节点
void printNodes(Node *root, int level) {
    if (root == NULL)
      return;

    printNodes(root->lchild, level + 1);// 先遍历左子树

    int i;
    for (i = 0; i < level; i++) {
      printf("    ");// 打印空格,表示层级
    }

    if (root->data == ' ') {
      printf("^");// 打印^表示空节点
    } else {
      printf("%c", root->data);// 打印节点值
    }

    printf("\n");

    printNodes(root->rchild, level + 1);// 再遍历右子树
}

int main() {
    printf("请输入中序遍历序列(^表示为空):\n");
    Node *root = createThreadedBinaryTree();

    Node *pre = NULL;// 前驱结点初始化为空
    inorderThreaded(root, &pre);

    printf("\n打印线索二叉树节点图示化:\n");
    printNodes(root, level);

    return 0;
}
输入^A^没有打印任何东西:

为什么呢?哪里需要修改?

isdkz 发表于 2023-8-22 18:31:50

问题出在printNodes函数中的递归调用顺序。在printNodes函数中,先遍历右子树,再遍历左子树。这样会导致先打印右子树的节点,再打印左子树的节点。而在中序线索化过程中,左孩子为空的节点会被指向前驱节点,右孩子为空的节点会被指向后继节点。所以,我们需要先打印左子树的节点,再打印右子树的节点。

解决方法是将printNodes函数中的递归调用顺序调换一下,先遍历左子树,再遍历右子树。修改后的printNodes函数如下:

// 打印线索二叉树图示化节点
void printNodes(Node *root, int level) {
    if (root == NULL)
      return;

    printNodes(root->lchild, level + 1);// 先遍历左子树

    int i;
    for (i = 0; i < level; i++) {
      printf("    ");// 打印空格,表示层级
    }

    if (root->data == ' ') {
      printf("^");// 打印^表示空节点
    } else {
      printf("%c", root->data);// 打印节点值
    }

    printf("\n");

    printNodes(root->rchild, level + 1);// 再遍历右子树
}


通过将printNodes函数中的递归调用顺序调换,可以正确打印线索二叉树的节点图示化。

陶远航 发表于 2023-8-22 18:32:33

根据你提供的代码和截图,代码中存在一处问题导致没有正确打印线索二叉树。问题出现在printNodes()函数中的循环语句上。

请注意以下部分:

int i;
for (i = 0; i < level; i++) {
    printf("    ");// 打印空格,表示层级
}


你使用了四个空格来表示层级,但是在实际调用printNodes()函数时,level变量始终为0,因此无论多少层级,都只会打印四个空格。这就导致了输出的结果不正确。

为了解决这个问题,你可以将level作为函数参数传递,并在递归调用中更新它。修改后的代码如下所示:

void printNodes(Node *root, int level) {
    if (root == NULL)
      return;
   
    printNodes(root->rchild, level + 1);// 先遍历右子树
   
    int i;
    for (i = 0; i < level; i++) {
      printf("    ");// 打印空格,表示层级
    }
   
    if (root->data == ' ') {
      printf("^");// 打印^表示空节点
    } else {
      printf("%c", root->data);// 打印节点值
    }
   
    printf("\n");
   
    printNodes(root->lchild, level + 1);// 再遍历左子树
}


通过将level传递给递归函数,每次递归调用时会增加层级数量,并打印相应数量的空格,从而正确显示线索二叉树的层次结构。

希望这可以帮助到你!如果还有其他问题,请随时提问。
如果问题已经解决,请设置最佳答案

ba21 发表于 2023-8-22 19:04:48

按你的输入主函数,这里root不就是NULL。

    printf("请输入中序遍历序列(^表示为空):\n");
    Node *root = createThreadedBinaryTree();
    if(root==NULL)
    {

      printf("NULL\n");
    }




Node* createThreadedBinaryTree() {
    Node *p;
    char c;
    scanf("%c", &c);

if (c == '^') {// 遇到^符号表示此分支为空
      return NULL;
    }

yinda_peng 发表于 2023-8-22 20:36:03

ba21 发表于 2023-8-22 19:04
按你的输入主函数,这里root不就是NULL。

    printf("请输入中序遍历序列(^表示为空):\n");


但是我想着还是绕不开这个赋值为NULL,创建线索二叉树的逻辑方面应该是没问题的,打印算是题外话也无所谓了,明天我看看小甲鱼的代码学习学习吧
页: [1]
查看完整版本: 求助:为什么没打印?