C中的二进制搜索树。程序不起作用。

时间:2017-03-07 15:22:52

标签: c binary-search-tree

我尝试通过C编程实现二进制搜索树。我只写了两个函数。该程序编译完美。但是当它运行时,它可以让用户“输入要插入的数据”。插入数据后,程序正在停止。

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

typedef struct Node
{
    int info;
    struct Node *left;
    struct Node *right;
}node;


node* insert(node *root, int data);
void inorder(node* root);


int main()
{
    int data,choice;
    node *root;
    printf("----------------MENU---------------\n");
    printf("1. Insert\n");
    printf("2.Inorder traversal\n");
    printf("3.Exit\n");
    while(1)
    {
        printf("Enter your choice: ");
        scanf("%d",&choice);
        switch(choice)
        {
            case 1: 
            printf("Enter the data to be inserted: ");
            scanf("%d",&data);
            root=insert(root,data);
            break;
            case 2:inorder(root);
            break;
            case 3:
                exit(0);
        }
    }
    return 0;
}

node* insert(node *root, int data)
{
    if(root==NULL)
    {
        root=(node *)malloc(sizeof(node));
        root->info=data;
        root->left=root->right=NULL;
        return root;
    }
    else if(data<=root->info)
    {
        root->left=insert(root->left,data);
        return root;
    }
    else if(data>=root->info)
    {
        root->right=insert(root->right,data);
        return root;
    }
}

void inorder(node* root)
{
    if(root==NULL)
    return;

    else
    {
    inorder(root->left);
    printf("%d",root->info);
    inorder(root->right);

    }

}

1 个答案:

答案 0 :(得分:0)

诊断

您没有初始化root(因此它不可靠地为NULL);你把它传递给insert(); insert()使用它并且事情变得混乱。

node *root = 0;   // Or NULL

通过此更改,代码将运行。打印不会在数字之间留下空格,这有点难看,但功能似乎没问题。您不仅需要编写代码来释放已分配的树。

评论

我观察到当我使用我使用的默认选项编译代码时(在使用GCC 6.3.0运行macOS Sierra 10.12.3的Mac上),我会收到警告。我将您的代码保存到ub37.c

$ gcc -O3 -g -std=c11 -Wall -Wextra -Werror -Wmissing-prototypes \
>     -Wstrict-prototypes -Wold-style-definition -c ub37.c
ub37.c:16:5: error: function declaration isn’t a prototype [-Werror=strict-prototypes]
 int main()
     ^~~~
ub37.c: In function ‘main’:
ub37.c:16:5: error: old-style function definition [-Werror=old-style-definition]
ub37.c: In function ‘insert’:
ub37.c:63:1: error: control reaches end of non-void function [-Werror=return-type]
 }
 ^
ub37.c: In function ‘main’:
ub37.c:33:17: error: ‘root’ may be used uninitialized in this function [-Werror=maybe-uninitialized]
             root=insert(root,data);
             ~~~~^~~~~~~~~~~~~~~~~~
cc1: all warnings being treated as errors
$

通过编写int main(void)来解决'严格原型'和'旧样式定义'警告。这不是世界末日的问题,但很容易解决。

可以通过在else if中仅使用else替换最终insert()来解决“控件到达非空函数的结尾”。我观察到>=的平等部分也被前面的else if (data = root->info)测试所覆盖。在某种程度上,这并不重要 - 您已经涵盖了所有案例。在另一个层面,它很容易修复,固定代码可以做你想要的,所以应该修复它。

主要错误由“root可能会使用未初始化”错误标识。

因为我也使用-Werror进行编译,所以这些警告中的任何一个都会阻止代码编译。

确保您使用类似严格的警告选项进行编译。它使您的代码更好。