二进制搜索树输出文件不是预期的输出数据

时间:2015-02-14 20:41:06

标签: c binary-tree binary-search-tree c-strings

好的,我正在创建一个二进制搜索树,它读入字符串并将它们存储在树中。我试图确认每个字符串都有它自己的节点,并且每个字符串实际上都被读入。当我的程序运行时,我相信它创建了七个节点,一个用于输入文件中的每个字符串。所以我创建了一个输出文件,用于打印刚读取的字符串,以确保每个字符串都存储在节点中。我的输入文件中有七个字符串:

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

现在每个文件中有七个字符串,所以我假设每个文件都被读取。但是,如何知道我的程序是否为每个字符串成功创建了一个节点? 我该如何解决这个问题?任何帮助,将不胜感激!谢谢!

3 个答案:

答案 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)

问题在于您的打印方式。在插入算法中,您永远不会修改节点中的字符串。但是,当您打印时,您每次都打印根。所以,你有几个选择:

  1. 使用调试器作为@JoachimPileborg建议。
  2. 打印输入字符串s以查看它是否正确地从输入中读取。
  3. 编写另一个函数来遍历树,并在每个节点中打印出字符串。这是最复杂的,但以后可能会有用。

答案 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