目前我试图将我文件中的每个单独行存储到一个字符串中,然后将其存储在二叉搜索树中,但是会出现问题。出于某种原因,当我打印我的BST时,只输出最后一行,而不是第一行。下面是我的代码。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct node
{
int count;
char* key;
struct node* left;
struct node* right;
};
struct node *newNode(char* item)
{
struct node* temp = (struct node*)malloc(sizeof(struct node));
temp->key = item;
temp->left = NULL;
temp->right = NULL;
temp->count = 1;
return temp;
};
void printInorder(struct node* root)
{
if(root != NULL)
{
printInorder(root->left);
printf("%s \n", root->key);
printInorder(root->right);
}
}
struct node* insert(struct node* node, char* key)
{
if(node == NULL)//When tree is empty
return newNode(key);
if(strcmp(key, node->key) < 0)
node->left = insert(node->left, key);
if(strcmp(key, node->key) > 0)
node->right = insert(node->right, key);
return node;
};
int main()
{
struct node *root = NULL;
int i = 0;
char str[100];
FILE* fp;
fp = fopen("textFile.txt", "r");
if ((fp = fopen("textFile.txt","r")) == NULL)
{
printf("Could not open textFile.txt\n");
exit(1);
}
while(fgets(str, 100, fp) != NULL)
{
++i;
root = insert(root, str);
printf("%3d: %s", i, str);
}
printf("bst printed\n");
printInorder(root);
return 0;
}
textFile.txt包含
bob is working.
david is a new hire.
alice is bob's boss.
charles doesn't like bob.
当打印出bst时,输出的唯一一行是最后一行 查尔斯不喜欢鲍勃。
真的很感激任何帮助。
答案 0 :(得分:3)
请注意,使用newNode创建节点时,会存储传递给它的指针的副本,而不是指向的字符串的副本。这意味着每次向树中插入值时,它都会在main中存储指向str缓冲区的指针。换句话说,在您第一次插入后,事情看起来像这样:
+------------+
| BST Node | str
+------------+ +---+---+---+---+---+...+---+
| key | ---------> | b | o | b | | i | | 0 |
+------------+ +---+---+---+---+---+...+---+
当你读到文件的下一行时,你用这行的内容覆盖str
,所以图片看起来像这样:
+------------+
| BST Node | str
+------------+ +---+---+---+---+---+...+---+
| key | ---------> | d | a | v | i | d | | 0 |
+------------+ +---+---+---+---+---+...+---+
请注意,即使您从未插入该值,您的BST现在就像包含“david是新员工”一样。因此,当您尝试将“david is a new hire”插入BST时,没有任何反应。
接下来的几次读取会发生同样的事情,直到最后你读到文件的最后一行,当事情看起来像这样:
+------------+
| BST Node | str
+------------+ +---+---+---+---+---+...+---+
| key | ---------> | c | h | a | r | l | | 0 |
+------------+ +---+---+---+---+---+...+---+
这就是为什么你最后只看到关于查理的这一行--BST正在指引您到缓冲区的单个共享副本。
要解决此问题,请使BST存储传入其中的字符串的副本,或者在将字符串存储到树中之前复制字符串。例如,您可能需要newNode
函数调用strdup
来获取自己要存储的字符串副本:
struct node *newNode(char* item)
{
struct node* temp = (struct node*)malloc(sizeof(struct node));
temp->key = strdup(item); // <--- here!
/* TODO: Error-handling! */
temp->left = NULL;
temp->right = NULL;
temp->count = 1;
return temp;
};
这应该可以解决您的问题。只要确保在完成后取消分配所有内容!