鱼C论坛

 找回密码
 立即注册
查看: 1522|回复: 7

[已解决]求助:为什么没打印?

[复制链接]
发表于 2023-8-22 18:31:33 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

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

代码:

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

  3. // 定义线索二叉树结点的结构体
  4. typedef struct Node {
  5.     struct Node *lchild;
  6.     int ltag;
  7.     char data;
  8.     int rtag;
  9.     struct Node *rchild;
  10. } Node;

  11. int level = 0;  // 当前层数

  12. // 创建线索二叉树
  13. Node* createThreadedBinaryTree() {
  14.     Node *p;
  15.     char c;
  16.     scanf("%c", &c);

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

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

  26.     return p;
  27. }

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

  32.         // 处理当前结点
  33.         if (p->lchild == NULL) {  // 左孩子为空,将ltag置为1,指向前驱结点
  34.             p->ltag = 1;
  35.             p->lchild = *pre;
  36.         }
  37.         
  38.         if (*pre != NULL && (*pre)->rchild == NULL) {  // 前驱结点的右孩子为空,将rtag置为1,指向后继结点
  39.             (*pre)->rtag = 1;
  40.             (*pre)->rchild = p;
  41.         }

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

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

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

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

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

  60.     printf("\n");

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

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

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

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

  70.     return 0;
  71. }
复制代码
输入^A^没有打印任何东西:
屏幕截图 2023-08-22 182246.png
为什么呢?哪里需要修改?
最佳答案
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;
    }

小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2023-8-22 18:31:50 | 显示全部楼层
问题出在printNodes函数中的递归调用顺序。在printNodes函数中,先遍历右子树,再遍历左子树。这样会导致先打印右子树的节点,再打印左子树的节点。而在中序线索化过程中,左孩子为空的节点会被指向前驱节点,右孩子为空的节点会被指向后继节点。所以,我们需要先打印左子树的节点,再打印右子树的节点。

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

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

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

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

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

  15.     printf("\n");

  16.     printNodes(root->rchild, level + 1);  // 再遍历右子树
  17. }
复制代码


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

点评

并没有解决,但或许是应该先遍历左子树  发表于 2023-8-22 18:41
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-8-22 18:32:33 | 显示全部楼层
根据你提供的代码和截图,代码中存在一处问题导致没有正确打印线索二叉树。问题出现在printNodes()函数中的循环语句上。

请注意以下部分:

  1. int i;
  2. for (i = 0; i < level; i++) {
  3.     printf("    ");  // 打印空格,表示层级
  4. }
复制代码


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

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

  1. void printNodes(Node *root, int level) {
  2.     if (root == NULL)
  3.         return;
  4.    
  5.     printNodes(root->rchild, level + 1);  // 先遍历右子树
  6.    
  7.     int i;
  8.     for (i = 0; i < level; i++) {
  9.         printf("    ");  // 打印空格,表示层级
  10.     }
  11.    
  12.     if (root->data == ' ') {
  13.         printf("^");  // 打印^表示空节点
  14.     } else {
  15.         printf("%c", root->data);  // 打印节点值
  16.     }
  17.    
  18.     printf("\n");
  19.    
  20.     printNodes(root->lchild, level + 1);  // 再遍历左子树
  21. }
复制代码


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

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

点评

不是这里的问题吧  发表于 2023-8-22 18:42
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 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;
    }

点评

给你最佳了  发表于 2023-8-22 20:36
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2023-8-22 20:36:03 | 显示全部楼层
ba21 发表于 2023-8-22 19:04
按你的输入主函数,这里root不就是NULL。

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

但是我想着还是绕不开这个赋值为NULL,创建线索二叉树的逻辑方面应该是没问题的,打印算是题外话也无所谓了,明天我看看小甲鱼的代码学习学习吧
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-6-10 00:16

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表