C 实现搜索功能后的二叉树分割错误
我正试图写一个程序,将做以下事情C 实现搜索功能后的二叉树分割错误,c,segmentation-fault,structure,binary-tree,C,Segmentation Fault,Structure,Binary Tree,我正试图写一个程序,将做以下事情 -read a file from std in -read each line, and add each line to a binary tree *if name is already in binary tree,dont add the name to the tree again but update its count of repititions -print out the binary tree 正在读取的文件看起来像 dylan bo
-read a file from std in
-read each line, and add each line to a binary tree
*if name is already in binary tree,dont add the name to the tree again but update its count of repititions
-print out the binary tree
正在读取的文件看起来像
dylan
bob
dylan
randall
randall
所以当我打印出二叉树时,我希望它打印出来
bob 1
dylan 2
randall 2
我能够成功地打印出姓名,而不用担心重复。我已经注释掉了那些把我的程序弄得一团糟的代码块,这些代码块与我的搜索函数交互,我在事后添加了搜索函数来处理重复。该代码构建了一个二叉树,每个“左”是一个由4部分组成的结构,即名称、计数以及指向左、右child的指针
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct node {
char* name;
int count;
struct node* left;
struct node* right;
};
struct node* addNode(char* string);
void insert(struct node *root, char* stringgg);
void preorder(struct node *root);
int search(struct node* leaf,char* string2find);
int main()
{
char buffer[20];
struct node *root = NULL;
while( fgets(buffer, sizeof(buffer), stdin) != NULL )
{
if(root == NULL)
root = addNode(buffer);
else
insert(root,buffer);
}
preorder(root);
}
struct node* addNode(char* string)
{
struct node *temp = malloc(sizeof(struct node));
temp->name = malloc(strlen(string) + 1);
strcpy(temp->name,string);
temp->left = NULL;
temp->right = NULL;
return temp;
}
void insert(struct node *root, char* stringgg)
{
/* int flag = 5;
flag = search(root,stringgg);
if(flag == 1)
return; */
if(strcmp(stringgg,root->name) < 0)
{
if(root->left == NULL)
root->left = addNode(stringgg);
else
insert(root->left, stringgg);
}
else
{
if(root->right == NULL)
root->right = addNode(stringgg);
else
insert(root->right,stringgg);
}
}
/*int search(struct node* leaf,char* string2find)
{
if(strcmp(string2find,leaf->name) == 0)
{
leaf->count = leaf->count + 1;
return 1;
}
else if(strcmp(string2find,leaf->name) < 0)
{
return search(leaf->left,string2find);
}
else
{
return search(leaf->right,string2find);
}
return 0;
} */
void preorder(struct node *root)
{
if(root == NULL)
return;
printf("%s",root->name);
preorder(root->left);
preorder(root->right);
}
#包括
#包括
#包括
结构节点{
字符*名称;
整数计数;
结构节点*左;
结构节点*右;
};
结构节点*添加节点(字符*字符串);
void insert(结构节点*root,字符*stringgg);
无效预订单(结构节点*根);
int搜索(结构节点*leaf,char*string2find);
int main()
{
字符缓冲区[20];
结构节点*root=NULL;
while(fgets(buffer,sizeof(buffer),stdin)!=NULL)
{
if(root==NULL)
root=addNode(缓冲区);
其他的
插入(根、缓冲区);
}
前序(根);
}
结构节点*添加节点(字符*字符串)
{
结构节点*temp=malloc(sizeof(结构节点));
temp->name=malloc(strlen(string)+1);
strcpy(临时->名称,字符串);
temp->left=NULL;
temp->right=NULL;
返回温度;
}
空插入(结构节点*根,字符*字符串)
{
/*int标志=5;
标志=搜索(根,stringgg);
如果(标志==1)
返回*/
if(strcmp(stringgg,root->name)<0)
{
如果(根->左==NULL)
root->left=addNode(stringgg);
其他的
插入(根->左,stringgg);
}
其他的
{
如果(根->右==NULL)
root->right=addNode(stringgg);
其他的
插入(根->右,stringgg);
}
}
/*int搜索(结构节点*leaf,char*string2find)
{
if(strcmp(string2find,leaf->name)==0)
{
叶->计数=叶->计数+1;
返回1;
}
else if(strcmp(string2find,leaf->name)<0)
{
返回搜索(叶->左,string2find);
}
其他的
{
返回搜索(叶->右,string2find);
}
返回0;
} */
无效预订单(结构节点*根)
{
if(root==NULL)
回来
printf(“%s”,根->名称);
预订单(根->左);
预订单(根->右);
}
上面的代码打印出所有名称,即使树中已经有名称。我希望有人能指出我的搜索功能错误,这样在打印时就不会导致分割错误。可能的原因可能是我不恰当地使用了return函数,在这个函数中,我试图返回main if flag==1,这意味着找到了匹配项,所以不要添加节点。但如果flag不等于1,则找不到匹配项,因此继续添加节点。在main
while( fgets(buffer, sizeof(buffer), stdin) != NULL ){
char *p = strchr(buffer, '\n');
if(p) *p=0;//remove '\n'
在addNode
temp->count = 1;//initialize counter
return temp;
插入时
void insert(struct node *root, char* stringgg){
int cmp_stat = strcmp(stringgg,root->name);
if(cmp_stat == 0)
root->count++;
else if(cmp_stat < 0) {
if(root->left == NULL)
root->left = addNode(stringgg);
else
insert(root->left, stringgg);
} else {
if(root->right == NULL)
root->right = addNode(stringgg);
else
insert(root->right,stringgg);
}
}
错误在于搜索空树中的第一个项目-您调用
search(root, stringgg)
但是root
是NULL
,所以在search()
中调用
strcmp(string2find, leaf->name)
使用leaf==NULL
时,程序崩溃
解决方法:在更新树之前不要搜索,而是通过搜索来更新它
struct node* update(struct node* nd, const char* str)
{
int cmp;
// (sub)tree is empty? - create a new node with cnt==1
if(nd == NULL)
return CreateNode(str);
// test if the node found
cmp = strcmp(str, nd->name);
if(cmp == 0) // YES
nd->count ++; // update the counter
else if(cmp < 0) // NO - search in a subtree
nd->left = update(nd->left, str);
else
nd->right = update(nd->right, str);
return nd; // return the updated subtree
}
实际上,
root
值在第一次调用时只会更改一次,并且所有后续赋值都不会更改其值。但是,这会使代码更具可读性。首先解决这个问题:在else
之后和insert(根,缓冲区)之前有一个不必要的新行在main()
函数中的code>。确保它是一个可编译的代码。尽管与当前的问题没有多大关系,但我想指出,intmain()
不一定是C
,intmain(void)
是!如何退出fgets
循环?在友好的本地调试器下运行时发生了什么事?@wedapasi:standard(ISO/IEC 9899:2011)在§5.1.2.2.1程序启动中说:[main
]应使用int
的返回类型定义,并且不带参数:int main(void){/*…*/}
…或同等产品。尽管我总是编写intmain(void)
(因为我使用GCC选项进行编译,例如-Wstrict原型
或-Wold样式定义
),但编写intmain()
并没有错,因为这是一个没有参数的函数。作为其他函数的声明,int otherfunc()代码>是错误的;它表示“没有关于参数的信息”,应该是int otherfunc(void)代码>。
struct node* update(struct node* nd, const char* str)
{
int cmp;
// (sub)tree is empty? - create a new node with cnt==1
if(nd == NULL)
return CreateNode(str);
// test if the node found
cmp = strcmp(str, nd->name);
if(cmp == 0) // YES
nd->count ++; // update the counter
else if(cmp < 0) // NO - search in a subtree
nd->left = update(nd->left, str);
else
nd->right = update(nd->right, str);
return nd; // return the updated subtree
}
root = update(root, buffer);