[英]segmentation fault in binary tree in C
我正在尝试实现我的代码以C语言创建一个二进制树。该代码没有给出任何错误,但在运行时会导致分段错误。无法确定原因。 请帮忙。
#include<stdio.h>
#include<malloc.h>
struct node{
int value;
struct node *left;
struct node *right;
}*root = NULL;
struct node* create(int val)
{
struct node *ptr;
ptr = (struct node*)malloc(sizeof(struct node));
ptr->value = val;
ptr->left = NULL;
ptr->right = NULL;
return ptr;
}
void insert(int val)
{
if(root == NULL)
{
root=create(val);
}
else if(val < (root)->value)
{
(root)->left = create(val);
}
else
{
(root)->right = create(val);
}
}
void traverse(struct node** root)
{
if(*root==NULL)
printf("TREE EMPTY");
return 0;
while((*root)!=NULL)
{
printf("%d",(*root)->value);
traverse((*root)->left);
traverse((*root)->right);
}
}
int main()
{
int val;
char ch='y';
while(ch=='y')
{
scanf("%d",&val);
insert(val);
printf("Want to insert more elements ?(y or n) =");
scanf("%c",ch);
}
traverse(&root);
free(root);
return 0;
}
正如@BLUEPIXY描述的分段错误通过解析变量的值而引起ch
代替的地址ch
。 除此之外,您的代码似乎还存在一些逻辑错误。
您的insert
实现仅查看根节点,并根据根值将新值添加到其左或右子级。 插入的理想行为是向下搜索树结构,直到到达叶节点,然后在此处插入新值。
如@BLUEPIXY所示, traverse
函数中的while ((*root)!=NULL)
等于while (true)
,因为根元素从未更新。 这里,再次, traverse
功能的期望行为是导航树结构(通常从左到右)并递归访问当前节点的子代。 下面的代码通过简单地在每个儿童上调用traverse而没有while循环,从而实现了一种简单的方法。
最后,正如@BLUEPIXY指出的那样,以root
为参数调用free
不会释放整个树。 Free
仅释放其参数指向的内存块。 它不会以递归方式跟随该内存块中的指针。 为了释放树结构所拥有的所有资源,您需要再次遍历树并在每个节点上free
调用。
以下代码基于您的代码,实现了二叉树。 请注意,树长大后不太可能保持平衡。 为了获得平衡的二叉树,您需要在插入新节点时对树进行重塑。
#include <stdio.h>
#include <stdlib.h>
typedef struct node{
int value;
struct node *left;
struct node *right;
} node;
node *root = NULL;
node* create(int val)
{
node *ptr;
ptr = (node*)malloc(sizeof(node));
ptr->value = val;
ptr->left = NULL;
ptr->right = NULL;
return ptr;
}
void insert_(node *root, int val)
{
if (val < root->value)
{
if (root->left != NULL)
{
insert_(root->left, val);
} else {
root->left = create(val);
}
}
else
{
if (root->right != NULL)
{
insert_(root->right, val);
} else {
root->right = create(val);
}
}
}
void insert(int val)
{
if(root == NULL)
{
root = create(val);
}
else
{
insert_(root, val);
}
}
void traverse(node *root)
{
if(root == NULL)
{
printf("E");
return;
}
printf("%d (", root->value);
traverse(root->left);
printf( ") (");
traverse(root->right);
printf( ")");
}
void free_tree(node *root)
{
if (root == NULL) {
return;
}
free_tree(root->left);
free_tree(root->right);
free(root);
}
int main()
{
int val;
char ch='y';
while(ch=='y')
{
scanf("%d",&val);
insert(val);
printf("Want to insert more elements ?(y or n) =");
scanf(" %s", &ch);
}
traverse(root);
free_tree(root);
return 0;
}
问题出在您的traverse()函数上。
printf()
语句并return 0
语句的括号; 如果您不这样做,那么它将首先检查(root是否为NULL)是否是->然后打印语句“ TREE EMPTY”并返回; 如果没有->它直接从函数返回。
void traverse ( struct node **root )
{
if ( *root == NULL )
{
printf ("TREE EMPTY");
return 0;
}
while ((*root) != NULL )
{
printf ("%d", (*root) -> value);
traverse ((*root) -> left);
traverse ((*root) -> right);
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.