我正在尝试编写一个将执行以下操作的程序
-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
我能够成功打印出名字而不必担心重复。我已经注释掉了使我的程序混乱的代码块,这是与我的搜索功能相互作用的任何东西,我在事后处理重复。代码构建了一个二叉树,每个“leave”是一个由4个部分组成的结构,即name,thecount和指向左右孩子的指针。
#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);
}
上面的代码打印出所有名称,即使已经存在于树中。我希望有人能够指出我的搜索功能错误,以便在打印时不会导致分段错误。可能的原因可能是我不恰当地使用return函数,其中我试图返回main如果flag == 1这意味着匹配被发现所以不添加节点。但是如果flag不等于1则没有找到匹配,那么就去添加节点。
答案 0 :(得分:0)
at main
while( fgets(buffer, sizeof(buffer), stdin) != NULL ){
char *p = strchr(buffer, '\n');
if(p) *p=0;//remove '\n'
at 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);
}
}
预购
printf("%s %d\n",root->name, root->count);
答案 1 :(得分:0)
错误在于搜索空树中的第一项 - 您调用
search(root, stringgg)
但root
为NULL
,因此在search()
中您可以调用
strcmp(string2find, leaf->name)
leaf == NULL
,程序崩溃。
治愈:不要搜索 BEFORE 更新树,而是搜索 TO 更新它。
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
}
然后在main()
中,您只需更新树并存储它:
root = update(root, buffer);
实际上,root
值在第一次调用时只会更改一次,并且所有后续分配都不会更改其值。然而,这使代码更具可读性。