二叉搜索树输出文件不是预期的输出数据
Binary search tree output file is not the expected output data
好的,我正在创建一个二进制搜索树,它读取字符串并将它们存储在树中。我试图确认每个字符串都有自己的节点,并且每个字符串实际上都被读入。当我的程序是 运行 时,我相信它正在创建七个节点,每个节点对应输入文件中的每个字符串。所以我创建了一个输出文件来打印刚刚读取的字符串,以确保每个字符串都存储在一个节点中。我的输入文件中有七个字符串:
bring
awake
anger
carry
global
fixed
halt
这是我的程序的代码:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAXLEN 15
typedef struct treeNode{
char string[MAXLEN+1];
struct treeNode *left;
struct treeNode *right;
}treeNode;
treeNode * insert(treeNode *node, char s[MAXLEN]){
puts("running insert");
if(node == NULL){
node = (treeNode *)malloc(sizeof(treeNode));
strncpy(node -> string, s, MAXLEN);
node -> left = NULL;
node -> right = NULL;
}
else if(strcmp(node->string, s)>0){
node -> right = insert(node->right, s);
}
else if(strcmp(node->string, s)<0){
node -> left = insert(node->left, s);
}
else if(strcmp(node->string, s) == 0){
node -> left = insert(node->left, s);
}
return node;
}
int main(int argc, char *argv[]){
treeNode *root = NULL;
FILE *ifp;
FILE *ofp;
char s[MAXLEN+1];
if(argc != 3){
fprintf(stderr, "Usage: %s file\n", argv[1]); exit(1);
}
if((ifp = fopen(argv[2], "r")) == NULL){
fprintf(stderr, "Could not open file: %s\n", argv[2]); exit(1);
}
ofp = fopen("output.txt", "w+");
while(fscanf(ifp, "%s\n", &s) != EOF){
root = insert(root, s);
fprintf(ofp, "%s\n", root->string);
}
return 0;
}
这是 运行 运行程序后输出文件的样子:
bring
bring
bring
bring
bring
bring
bring
现在每个文件中有七个字符串,所以我假设每个文件都已读取。但是我怎么知道我的程序是否成功地为每个字符串创建了一个节点呢?
我该如何解决这个问题?任何帮助,将不胜感激!谢谢!
已修复完整代码:http://pastebin.com/5BTnxTcd
其他优化代码,留给你。
看来你的问题是return。它需要像这样,因为你需要 return root of tree->
treeNode * insert(treeNode *node, char s[MAXLEN]){
puts("running insert");
if(node == NULL){
node = (treeNode *)malloc(sizeof(treeNode));
strncpy(node -> string, s, MAXLEN);
node -> left = NULL;
node -> right = NULL;
}
else if(strcmp(node->string, s)>0){
node -> right = insert(node->right, s);
}
else if(strcmp(node->string, s)<0){
node -> left = insert(node->left, s);
}
else if(strcmp(node->string, s) == 0){
node -> left = insert(node->left, s);
}
return node;
}
**编辑:** 看来您对 argv
也有问题,argv[0]
是程序名称
fprintf(stderr, "Usage: %s file\n", argv[1]); exit(1);
需要
fprintf(stderr, "Usage: %s file\n", argv[0]); exit(1);
编辑编辑 :
您需要函数对树进行递归处理,并先输出左侧然后输出右侧,它将是:
void treeprint( treeNode *node , FILE *OUTPUT_FILE)
{
if ( node != NULL)
{
treeprint(node->left , OUTPUT_FILE);
fprintf(OUTPUT_FILE , "%s" , node->string);
treeprint(node->right, OUTPUT_FILE);
}
}
并在 while
循环后调用,并调用 treeprint(root, ofp);
.
之类的函数
问题在于您的打印方式。在您的插入算法中,您永远不会修改节点中的字符串。但是,当您打印时,您每次都在打印根。所以,你有几个选择:
- 按照@JoachimPileborg 的建议使用调试器。
- 打印输入字符串
s
以查看是否从输入中正确读取了它。
- 编写另一个函数来遍历您的树并打印出每个节点中的字符串。这是最复杂的,但以后可能会有用。
让我们来谈谈您面临的问题:
您想知道您的程序是否成功地为每个字符串创建了一个节点。解决这个问题的方法不止一种。最简单的方法是在实际创建节点时打印出节点的值。因此您的代码将类似于:
treeNode * insert(treeNode *node, char s[MAXLEN]){
puts("running insert");
if(node == NULL){
node = (treeNode *)malloc(sizeof(treeNode));
strncpy(node -> string, s, MAXLEN);
node -> left = NULL;
node -> right = NULL;
**printToFile( root->string );**
}
else if(strcmp(node->string, s)>0){
node -> right = insert(node->right, s);
}
else if(strcmp(node->string, s)<0){
node -> left = insert(node->left, s);
}
else if(strcmp(node->string, s) == 0){
node -> left = insert(node->left, s);
}
return node;
}
这是打印到文件的辅助函数:
File* ofp; // Need to be declared globally or pass in functions as parameters
void openWritableFile()
{
ofp = fopen("output.txt", "w+");
}
void printToFile( char* data )
{
fprintf(ofp, "%s\n", data );
}
另一种方法是使用树遍历算法遍历整个树,例如按顺序、post-顺序或预序,但只能在创建完整的树之后。
以下是如何使用根元素进行中序遍历,从而打印树的内容:
void inorder(struct root* node)
{
if (root == NULL)
return;
inorder(root->left)
printToFile( root->string );
inorder(root->right);
}
你可以在这里了解树遍历:Tree Traversal
好的,我正在创建一个二进制搜索树,它读取字符串并将它们存储在树中。我试图确认每个字符串都有自己的节点,并且每个字符串实际上都被读入。当我的程序是 运行 时,我相信它正在创建七个节点,每个节点对应输入文件中的每个字符串。所以我创建了一个输出文件来打印刚刚读取的字符串,以确保每个字符串都存储在一个节点中。我的输入文件中有七个字符串:
bring
awake
anger
carry
global
fixed
halt
这是我的程序的代码:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAXLEN 15
typedef struct treeNode{
char string[MAXLEN+1];
struct treeNode *left;
struct treeNode *right;
}treeNode;
treeNode * insert(treeNode *node, char s[MAXLEN]){
puts("running insert");
if(node == NULL){
node = (treeNode *)malloc(sizeof(treeNode));
strncpy(node -> string, s, MAXLEN);
node -> left = NULL;
node -> right = NULL;
}
else if(strcmp(node->string, s)>0){
node -> right = insert(node->right, s);
}
else if(strcmp(node->string, s)<0){
node -> left = insert(node->left, s);
}
else if(strcmp(node->string, s) == 0){
node -> left = insert(node->left, s);
}
return node;
}
int main(int argc, char *argv[]){
treeNode *root = NULL;
FILE *ifp;
FILE *ofp;
char s[MAXLEN+1];
if(argc != 3){
fprintf(stderr, "Usage: %s file\n", argv[1]); exit(1);
}
if((ifp = fopen(argv[2], "r")) == NULL){
fprintf(stderr, "Could not open file: %s\n", argv[2]); exit(1);
}
ofp = fopen("output.txt", "w+");
while(fscanf(ifp, "%s\n", &s) != EOF){
root = insert(root, s);
fprintf(ofp, "%s\n", root->string);
}
return 0;
}
这是 运行 运行程序后输出文件的样子:
bring
bring
bring
bring
bring
bring
bring
现在每个文件中有七个字符串,所以我假设每个文件都已读取。但是我怎么知道我的程序是否成功地为每个字符串创建了一个节点呢? 我该如何解决这个问题?任何帮助,将不胜感激!谢谢!
已修复完整代码:http://pastebin.com/5BTnxTcd 其他优化代码,留给你。
看来你的问题是return。它需要像这样,因为你需要 return root of tree->
treeNode * insert(treeNode *node, char s[MAXLEN]){
puts("running insert");
if(node == NULL){
node = (treeNode *)malloc(sizeof(treeNode));
strncpy(node -> string, s, MAXLEN);
node -> left = NULL;
node -> right = NULL;
}
else if(strcmp(node->string, s)>0){
node -> right = insert(node->right, s);
}
else if(strcmp(node->string, s)<0){
node -> left = insert(node->left, s);
}
else if(strcmp(node->string, s) == 0){
node -> left = insert(node->left, s);
}
return node;
}
**编辑:** 看来您对 argv
也有问题,argv[0]
是程序名称
fprintf(stderr, "Usage: %s file\n", argv[1]); exit(1);
需要
fprintf(stderr, "Usage: %s file\n", argv[0]); exit(1);
编辑编辑 : 您需要函数对树进行递归处理,并先输出左侧然后输出右侧,它将是:
void treeprint( treeNode *node , FILE *OUTPUT_FILE)
{
if ( node != NULL)
{
treeprint(node->left , OUTPUT_FILE);
fprintf(OUTPUT_FILE , "%s" , node->string);
treeprint(node->right, OUTPUT_FILE);
}
}
并在 while
循环后调用,并调用 treeprint(root, ofp);
.
问题在于您的打印方式。在您的插入算法中,您永远不会修改节点中的字符串。但是,当您打印时,您每次都在打印根。所以,你有几个选择:
- 按照@JoachimPileborg 的建议使用调试器。
- 打印输入字符串
s
以查看是否从输入中正确读取了它。 - 编写另一个函数来遍历您的树并打印出每个节点中的字符串。这是最复杂的,但以后可能会有用。
让我们来谈谈您面临的问题: 您想知道您的程序是否成功地为每个字符串创建了一个节点。解决这个问题的方法不止一种。最简单的方法是在实际创建节点时打印出节点的值。因此您的代码将类似于:
treeNode * insert(treeNode *node, char s[MAXLEN]){
puts("running insert");
if(node == NULL){
node = (treeNode *)malloc(sizeof(treeNode));
strncpy(node -> string, s, MAXLEN);
node -> left = NULL;
node -> right = NULL;
**printToFile( root->string );**
}
else if(strcmp(node->string, s)>0){
node -> right = insert(node->right, s);
}
else if(strcmp(node->string, s)<0){
node -> left = insert(node->left, s);
}
else if(strcmp(node->string, s) == 0){
node -> left = insert(node->left, s);
}
return node;
}
这是打印到文件的辅助函数:
File* ofp; // Need to be declared globally or pass in functions as parameters
void openWritableFile()
{
ofp = fopen("output.txt", "w+");
}
void printToFile( char* data )
{
fprintf(ofp, "%s\n", data );
}
另一种方法是使用树遍历算法遍历整个树,例如按顺序、post-顺序或预序,但只能在创建完整的树之后。
以下是如何使用根元素进行中序遍历,从而打印树的内容:
void inorder(struct root* node)
{
if (root == NULL)
return;
inorder(root->left)
printToFile( root->string );
inorder(root->right);
}
你可以在这里了解树遍历:Tree Traversal