【问题标题】:How can I create a BST by reading from a text file?如何通过读取文本文件来创建 BST?
【发布时间】:2019-05-26 07:56:21
【问题描述】:

我必须创建一个学生数据库,其中包含他们的 ID、姓名、姓氏和年级。此信息是从如下所示的 txt 文件中读取的:

AE797989 Spears Michael 10.00
AA566734 Walsh Brad 10.00
AE808090 Jones Dimitris 5.00
...

包含 19 名学生

我必须读取文件的每一行并根据它们的 ID 创建一个二叉搜索树。创建节点时似乎有问题,因为当我尝试搜索学生时,我不能。这是我的代码:

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

struct node
{
    struct node *left;
    char ID[100];
    char NAME[100];
    char LAST_NAME[100];
    float Grade;
    struct node *right;
};

struct node *newNode(char, char, char, float);
struct node *insertNode(struct node node, char id, char name, char last_name, float grade);
void search(struct node *root, char *ID);
void deleteFromBST(char *ID);

int main() 
{

  char ID[100];
  int insertDone = 0;
  int ch;

  while (1) {
    printf("\n1. Insertion\t2. Deletion\n");
    printf("3. Searching\t4. Display In Order\n5. Edit\t        6. Exit\n");
    printf("Enter your choice:");
    scanf("%d", &ch);


    switch (ch) {
    case 1: 
      if (insertDone)
        puts("Inserton was already done");
      else {
        struct node* insertNode(struct node *node,char *id, char *name, char *last_name, float grade)
        {
            if (node == NULL)
            return newNode(*id,*name,*last_name,grade);

            if ( strcmp(id , node->ID) < 0)
            node->left = insertNode(node->left,id,name,last_name,grade);

            else if ( strcmp( id , node->ID) >= 0)
            node->right = insertNode(node->right,id,name,last_name,grade);

            return node;
        }   
        insertDone = 1;
      }
      break;

    case 2:     
      break;

    case 3: 
      printf("Enter the AM to search:");
      scanf("%99s", ID);
      void search(struct node *root, char *ID)
        {
        int flag=0;

        if (!root) 
        {
        printf("Search element unavailable in BST\n");
        return;
        }

        while (root != NULL) {
        if (strcmp(root->ID, ID) == 0) {
            printf("Student ID  : %s\n", root->ID);
            printf("First Name     : %s\n", root->NAME);
            printf("Last Name     : %s\n", root->LAST_NAME);
            printf("grade      : %lg\n", root->Grade);
            flag = 1;
            break;
             }

        else if (strcmp(ID , root->ID) > 0)
        { 
         return search(root->right,ID); 
        }

        else if(strcmp(ID , root->ID) < 0)
        {
        return search(root->left,ID);
        }

          if (!flag)
          printf("Search element unavailable in BST\n");
        }
       }

      break;
    case 4: 
      //display();
      break;
    case 5:
      break;
    case 6: 
      exit(0);
    default: 
      printf("U have entered wrong option!!\n");
      break;
    }
  }
  struct node* newNode(char *id, char *name, char *last_name, float grade)
{

  struct node *newnode = malloc(sizeof(struct node));
  struct node Node;

  FILE *fp;
  fp = fopen ("Foitites-Vathmologio-DS.txt","rb");

  if (fp == NULL) 
  { 
    fprintf(stderr,"Could not open file");  
    return;
  } 

  char line[4096];

  while (fgets(line, sizeof line,fp)) 
  {
    size_t len = strlen(line);
    if (len && (line[len - 1] == '\n')) 
    {
      /* incomplete line */
      if (sscanf(line,"%99s %99s %99s %f",Node.ID, Node.NAME, Node.LAST_NAME, &Node.Grade) != 4) 
      {
      puts("invalid file");
      return;
      }

    strcpy(newnode->ID , id);
    strcpy(newnode->NAME , name);
    strcpy(newnode->LAST_NAME , last_name);
    newnode->Grade = grade;
    newnode->left = newnode->right = NULL;
    return newnode;

    }
  }
fclose(fp);
}
  return 0;
}

我没有收到任何错误消息。感谢您的宝贵时间!

【问题讨论】:

  • 您应该使用选项-Wall -Werror -std=c11 -pedantic 进行调查。当您在这里受苦时,这将抱怨嵌套函数。 nest19.c: In function ‘main’:——nest19.c:40:9: error: ISO C forbids nested functions [-Werror=pedantic]——40 | struct node* insertNode(struct node *node,char *id, char *name, char *last_name, float grade)。不幸的是,如果你不是迂腐的,你将不会收到警告(或错误,因为我使用了-Werror)。取消嵌套函数后,您需要实际调用它们。还有许多其他问题需要解决。

标签: c binary-search-tree nested-function


【解决方案1】:

如果您没有收到此代码的错误消息,我建议您使用不同的编译器。我在main 中窒息:

    switch (ch) {
    case 1:
        if (insertDone)
            puts("Inserton was already done");
        else {
            struct node* insertNode(struct node *node, char *id, char *name,
                   char *last_name, float grade)      // ERROR HERE
            {
                if (node == NULL)

看起来你复制了函数的定义,而不是仅仅调用它。

我的问题是您设法在一个程序中编写了许多不同的错误。而且程序结构的全局设计尚不清楚:看起来您在没有先在纸上写字的情况下开始编码(是的,纸和铅笔对于初学者来说仍然是非常好的工具)每个功能是什么应该做什么,它的输入是什么,它的输出应该是什么,最终它包含了什么数据(例如,负责文件名的部分)。当然,我可以为你写一个 BST 程序,但你不会从中学到任何东西。

所以这里有一些提示:

  • 在 BST 中,您在现有节点下插入新数据,因此您需要一个带有以下输入参数的函数 insertNode:当前根节点(或第一次为 NULL)、id、name、last_name 和要插入的等级.您应该构建输入字符串的新副本(strdup 是您的朋友)。此函数将分配一个新结构,填充字段,如果当前根为 NULL,则返回它,或者将其插入现有树中的正确位置
  • 您想处理文件中的所有行。您将需要一个打开文件的函数,逐行读取并使用前一个函数将新记录插入 BST

顺便说一句,函数定义类似于

struct node *insert(struct node *root, const char id*, const char *name, const char *last_name, float grade) {
    struct node * newnode = malloc(sizeof *newnode);
    ...
    return root;
}

在任何其他函数定义之外,而函数调用将类似于:

struc node *root = NULL;
char id[100], name[100], last_name[100];
float grade;
...
      if (sscanf(line,"%99s %99s %99s %f",id, name, last_name, &grade)) != 4) 
      {
      puts("invalid file");
      return;
      }
      root = insert(root, id, name, last_name, grade);  // here is the function call

【讨论】:

  • 我知道代码太大了,我只是把它全部放在那里,因为它可以帮助一些人阅读这样的问题。我在案例中编写了函数,因为我不熟悉调用结构函数,这给我带来了问题。
  • 编译器可能是 GCC,可能是 Clang 模拟 GCC。默认情况下接受嵌套函数,这对于新手 C 程序员来说是一个真正的 PITA。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-05-05
  • 1970-01-01
  • 2017-01-17
  • 2021-12-14
相关资源
最近更新 更多