【问题标题】:Why my Preoder, Inorder and Postorder functions are not working为什么我的 Preorder、Inorder 和 Postorder 功能不起作用
【发布时间】:2021-08-04 00:34:27
【问题描述】:
#include <stdio.h>
#include <stdlib.h>

节点创建

此结构创建结构节点数据类型

 struct node
    {
        int data;
        struct node *left, *right;
    } * newnode;

创建函数

create() - 它首先分配节点所需的内存。当用户输入数据时,它会递归地调用自己来创建它的子节点,并继续这个过程。当用户输入 -1 时,它会终止递归并从调用它的地方返回。

    struct node *create()
    {
        int x;
        newnode = (struct node *)malloc(sizeof(struct node));
        newnode->left = 0;
        newnode->right = 0;
        printf("Enter data(-1 for no node)\n");
        scanf("%d", &x);
        if (x == -1)
            return 0;
        newnode->data = x;
        printf("Enter left child of %d\n", x);
        newnode->left = create();
    
        printf("Enter right child of %d\n", x);
        newnode->right = create();
        return newnode;
    }

预购

preorder(struct node *root) - 该函数以先序方式显示树的数据

    void preorder(struct node *root)
    {
        if (root == 0)
            return;
    
        printf("%d\n", root->data);
        preorder(root->left);
        preorder(root->right);
    }

顺序

inorder(struct node *root) - 该函数将树的数据按顺序显示

    void inorder(struct node *root)
    {
        if (root == 0)
            return;
    
        inorder(root->left);
        printf("%d\n", root->data);
        inorder(root->right);
    }

后购

Postorder(struct node *root) - 该函数以后序方式显示树的数据

    void postorder(struct node *root)
    {
        if (root == 0)
            return;
    
        postorder(root->left);
        postorder(root->right);
        printf("%d\n", root->data);
    }

主要功能

Main 函数要求用户创建一棵树,然后根据用户输入的选择遍历它。问题是preorder、inorder和postorder都没有给出需要的输出,执行后导致死循环。

 void main()
    {
        struct node *root;
        root = 0;
        int choice = 3, opt = 1;
    
        while (opt)
        {
            printf("Select\n 1-for creation\n 2-for preorder\n 3-for inorder\n 4-for postorder\n");
            scanf("%d", &choice);
            switch (choice)
            {
            case 1:
                root = create();
                break;
            case 2:
                printf("Preorder is: ");
                preorder(root);
                break;
            case 3:
                printf("Inorder is: ");
                inorder(root);
                break;
            case 4:
                printf("Postorder is: ");
                postorder(root);
                break;
    
            default:
                printf("Invalid choice");
                break;
            }
            printf("Wanna continue \n1-for yes\n0-for no\n");
            scanf("%d", &opt);
        }
    }

【问题讨论】:

    标签: binary-tree recursive-datastructures inorder preorder postorder


    【解决方案1】:

    您提供的任何遍历函数都没有错误。 create () 函数也没有设计或实现问题。

    问题在于使用结构定义声明的全局struct node 指针newnode

    因为对create () 的每个递归调用基本上都使用“相同”的newnode 指针,所以树从来没有真正按照我们想要的方式构建。

    让我们尝试空运行create () 函数。

    假设我们想要一棵这样的树:

        1
       / \
      2   3
    
    1. create () 首先从 main 调用。
    • 内存使用malloc ()函数分配,内存地址存储在newnode中。
    • 设置它的属性,leftright
    • 请求data并将其放入data属性中,如果data == -1为真,return 0

    到目前为止,这就是状态:

    newnode -> 1
              / \
           Null  Null
    
    1. 递归调用create () 来构建左子树。
    • 使用malloc ()newnode分配内存,内存地址存储在newnode中。请注意,此操作基本上“改写了”先前存储在newnode 中的地址(因为newnode 是一个全局变量

    • 然后,系统将再次提示用户输入data,并设置其属性。

    因此,树现在变成了:

    newnode -> 2
              / \
           Null  Null
    

    newnode 之前指向的struct node 现在丢失了(因为丢失了它的地址)

    同样,当对右子树进行递归调用时,将观察到以下情况:

    newnode -> 3
              / \
           Null  Null
    

    考虑到其余递归调用的情况相同,很明显,最终我们期望的树没有构建,原因是 全局变量 newnode ,不断分配内存和覆盖newnode 中的地址只会导致内存泄漏

    发现无限递归的原因是,在多次递归调用过程中,newnodeleftright指针指向newnode本身,导致循环。在递归调用过程中,通过密切跟踪newnodedata 可以找到此节点。

    因此,从结构声明中删除newnode指针的声明,并修改create ()函数中的以下语句:

    newnode = (struct node *)malloc(sizeof(struct node));

    到这里:

    struct node * newnode = (struct node *)malloc(sizeof(struct node));

    struct node
    {
        int data;
        struct node *left, *right;
    };
    

    是所有需要的。

    这样,每次对create ()函数的递归调用都会有自己的局部指针变量newnode,并且不会覆盖,不会泄漏,不会循环,不会无限递归。

    【讨论】:

      猜你喜欢
      • 2021-06-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-08-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多