我尝试通过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);
}
}
答案 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
进行编译,所以这些警告中的任何一个都会阻止代码编译。
确保您使用类似严格的警告选项进行编译。它使您的代码更好。