二叉树代码无法正常工作

时间:2015-06-16 08:29:16

标签: c pointers

我制作了一个树形结构,从文件中读取单词并将它们注册到树中。但是enter()无法正常工作。我使用gdb进行了调试并设置了一个断点线42.然后我输入了print *node print *root

(gdb) print node
$9 = (struct node *) 0x603250
(gdb) print *node
$10 = {left = 0x0, right = 0x0, word = 0x0}
(gdb) print root
$11 = (struct node *) 0x0
(gdb) print *root
Cannot access memory at address 0x0

为什么root没有任何意义? 为什么node->word没有给出单词?

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>

struct node {
  struct node *left;
  struct node *right;
  char *word;
};

static struct node *root = NULL;

void memory_error(void) {
  fprintf(stderr, "Error: Out of memory\n");
  exit(8);
}

char *save_string(char *string) {
  char *new_string;

  new_string = malloc((unsigned) (strlen(string) + 1));

  if (new_string == NULL)
    memory_error();

  strcpy(new_string, string);

  return (new_string);
}

void enter(struct node *node, char *word) {
  int result;

  if (node == NULL) {
    node = malloc(sizeof(struct node));
    if (node == NULL)
      memory_error();

    node->left = NULL;
    node->right = NULL;
    node->word = save_string(word);
    return;
  }

  result = strcmp(node->word, word);

  if (result == 0)
    return;

  if (result < 0)
    enter(node->right, word);
  else
    enter(node->left, word);
}

void scan(char *name) {
  char word[100];
  int index;
  int ch;
  FILE *in_file;

  in_file = fopen(name, "r");
  if (in_file == NULL) {
    fprintf(stderr, "Error: Unable to open %s\n", name);
    exit(8);
  }

  while (1) {
    while (1) {
      ch = fgetc(in_file);

      if (isalpha(ch) || (ch == EOF))
    break;
    }

    if (ch == EOF)
      break;

    word[0] = ch;
    for (index = 1; index < sizeof(word); index++) {
      ch = fgetc(in_file);
      if (!isalpha(ch))
    break;
      word[index] = ch;
    }

    word[index] = '\0';

    enter(root, word);
  }

  fclose(in_file);
}

void print_tree(struct node *top) {
  if (top == NULL)
    return;

  print_tree(top->left);
  printf("%s\n", top->word);
  print_tree(top->right);
}

int main(int argc, char *argv[]) {
  if (argc != 2) {
    fprintf(stderr, "Error: Wrong number of parameters\n");
    fprintf(stderr, "       on the command line\n");
    fprintf(stderr, "Usage is:\n");
    fprintf(stderr, "         words 'file'\n");
    exit(8);
  }

  scan(argv[1]);
  print_tree(root);
  return (0);
}

我给这个程序提供了以下文本作为参数“a.txt”。

apple
orange
lemon
banana
pine
stroberry
ruby
perl
python
c

4 个答案:

答案 0 :(得分:5)

您从未指定root。因此,它将始终保持NULL

请注意,在enter中,您分配了一个节点,但实际上并未将结果节点保存在任何位置。您可能希望返回新节点并改为root = enter(root, word)

答案 1 :(得分:2)

正如@nneonneo指出的那样,您应该返回新修改的根,或者将root作为指针引用传递给void enter(struct node **node, char *word)并使用enter(&root, word);调用

答案 2 :(得分:1)

看起来您从未向root分配任何值。请记住,C按值传递参数,因此当您从enter(root, word);调用scan()时,enter()无法更改root的值。但是,它改变了它的本地副本,但这还不够。

递归调用enter时会出现同样的问题。

修复此问题的一种方法是将指针传递给节点指针,这样就可以这样改变:

enter(&root, word);

声明:

void enter(struct node **nodep, char *word) {

并调整其中node的所有用途,使其成为*nodep

答案 3 :(得分:0)

您在enter()中分配节点,但由于它是通过复制而不是引用传递的,因此节点不会在函数外部更改。

返回新节点root = enter(root, word)或通过引用传递:enter(&root, word),将enter的覆盖区域更改为void enter(struct node **node, char *word),将节点的所有实例更改为* node。