为什么我的 Preoder、Inorder 和 Postorder 函数不起作用 节点创建创建函数预购中序后序主要功能

问题描述

#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);
        }
    }

解决方法

您提供的任何遍历函数都没有错误。 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 () 被递归调用以构建左子树。
  • 使用newnodemalloc ()分配内存,内存地址存放在newnode中。请注意,此操作基本上“覆盖”了先前存储在 newnode 中的地址(因为 newnode 是一个全局变量

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

因此,这棵树现在变成了:

newnode -> 2
          / \
       Null  Null

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

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

newnode -> 3
          / \
       Null  Null

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

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

因此,从结构声明中删除newnode指针的声明并修改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 (),不会有覆盖、无泄漏、无循环、无无限递归。