好的,我正在创建一个二进制搜索树,它读入字符串并将它们存储在树中。我试图确认每个字符串都有它自己的节点,并且每个字符串实际上都被读入。当我的程序运行时,我相信它创建了七个节点,一个用于输入文件中的每个字符串。所以我创建了一个输出文件,用于打印刚读取的字符串,以确保每个字符串都存储在节点中。我的输入文件中有七个字符串:
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
现在每个文件中有七个字符串,所以我假设每个文件都被读取。但是,如何知道我的程序是否为每个字符串成功创建了一个节点? 我该如何解决这个问题?任何帮助,将不胜感激!谢谢!
答案 0 :(得分:1)
修复完整代码:http://pastebin.com/5BTnxTcd 其他优化代码,请留给您。
看来你的问题就是回归。它必须是这样的,因为你需要返回树的根 - &gt;
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);
等函数。
答案 1 :(得分:1)
问题在于您的打印方式。在插入算法中,您永远不会修改节点中的字符串。但是,当您打印时,您每次都打印根。所以,你有几个选择:
s
以查看它是否正确地从输入中读取。答案 2 :(得分:0)
让我们来看看您面临的问题: 您想知道您的程序是否成功为每个字符串创建了一个节点。有多种方法可以解决这个问题。最简单的方法是在实际创建节点时打印出该节点的值。因此,您的代码将类似于:
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 );
}
另一种方法是使用树遍历算法(例如有序,后序或预订)来遍历整个树,但仅在创建完整树之后。
以下是如何使用根元素进行遍历遍历,从而打印树的内容:
void inorder(struct root* node)
{
if (root == NULL)
return;
inorder(root->left)
printToFile( root->string );
inorder(root->right);
}
您可以在此处了解树遍历:Tree Traversal