我正在尝试实现我的代码来用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;
}
答案 0 :(得分:1)
如@BLUEPIXY所述,分段错误是由解析变量ch
的值而不是ch
的地址引起的。除此之外,您的代码似乎也有一些逻辑错误。
insert
的实现仅查看根节点,并根据根值将新值添加到其左或右子节点。所需的行为是插入向下搜索树结构,直到它到达叶节点,并在此处插入新值。
如@BLUEPIXY所示,while ((*root)!=NULL)
函数中的traverse
等于while (true)
,因为根元素永远不会更新。在这里,同样,期望的行为是traverse
函数导航树结构(通常从左到右)并递归地访问当前节点的子节点。下面的代码实现了一种简单的方法来实现这一点,只需在每个子节点上调用遍历,而不使用while循环。
最后,正如@BLUEPIXY也指出的那样,以free
作为参数调用root
并不会释放整个树。 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;
}
答案 1 :(得分: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);
}
}