【问题标题】:How to sort and search BST by name(string)?如何按名称(字符串)对 BST 进行排序和搜索?
【发布时间】:2014-03-24 06:43:59
【问题描述】:

我必须编写一个程序,将 .txt 文件读入树中,然后允许对其执行特定操作。我被困在需要按名称对树进行排序并按名称搜索的部分,任何输入都会很棒。所以,我的输入文件格式为:

3800 Lee, Victor; 2.8 
3000 Brown, Joanne; 4.0

而且,我的二叉树格式为:

typedef struct
 {
 int   id;
 char  name[MAX_NAME_LEN];
float gpa;
 } STUDENT;

typedef struct node
{
 STUDENT*        dataPtr;
 struct node* left;
 struct node* right;
} NODE;

typedef struct
{
 int   count;
 int  (*compare) (void* argu1, void* argu2); // Was provided by teacher, not really sure    how this works
 NODE*  root;
} BST_TREE;

ReadFile 和 insert 函数工作得很好,但我不知道如何实现按名称(字符串)搜索。我知道我必须使用这部分代码,但我真的不知道该怎么做。

/*  ====================== compareStu ======================
    Compare two student names's and return low, equal, high.
    Pre  stu1 and stu2 are valid pointers to students
    Post return low (-1), equal (0), or high (+1)
*/

int  compareStu   (void* stu1, void* stu2)
{
//  Local Definitions
STUDENT s1 = *((STUDENT*)stu1);
    STUDENT s2 = *((STUDENT*)stu2);;

//  Statements
if ( s1.name < s2.name)
      return -1;

if ( s1.name == s2.name)
      return 0;

return +1;
}   // compareStu

有人告诉我,我需要执行一组特定的操作,但我也没有理解它们,任何详细的解释或分步操作都会非常有用:

"您只需将 BST_TREE 的比较元素设置为 compareStu: BST_TREE 根 = { 0, cmp_by_name, 0 }; 然后,您使用 &root 作为树的根来调用您的函数。这不是您提供的比较功能。您应该使用单个比较函数来构建和搜索树;在不同的时间使用不同的比较器会导致混乱。” (c)Jonathan Leffler

"如果您在创建树时将其设置为树中的比较,则您已经显示的代码将使用 cmp_by_name() 函数。我不能再向您显示了;您还没有显示所有代码,并且我不准备为您编写代码只是为了演示我将如何做到这一点。我会注意名称 _retrieve() 不适合您使用;您应该将以 _ 开头的名称视为 '保留用于实现”(比这更细微,但不是很多,更简单的规则更容易记住)。您可以使用 if (root == NULL) return 0; else if (...)" 来简化代码(c)乔纳森·莱弗勒

因此:

1) 如何在树中搜索名称?

/*  ====================== findStu ======================
    Finds a student and prints id and gpa.
    Pre  student id
    Post student data printed or error message
*/

void findStu (BST_TREE* tree)
{
//  Local Definitions
STUDENT  s;
STUDENT* stuPtr;

//  Statements
printf("Enter student name that you want to find: ");
fflush(stdin);
gets(s.name);
fflush(stdin);

stuPtr = (STUDENT*)BST_Retrieve (tree, &s);
if (stuPtr)
   {
    printf("Student id:   %04d\n",  stuPtr->id);
    printf("Student name: %s\n",    stuPtr->name);
    printf("Student gpa:  %4.1f\n", stuPtr->gpa);
   } // if
else
   printf("Student %s has NOT been found in the file\n", s.name);
}   // findStu

2) 如何按名称对 BST 进行排序?我知道整数排序的工作原理以及值如何相互比较,但我不知道名称。

【问题讨论】:

  • 对于最后一个结构int (*compare) (void* argu1, void* argu2);是一个指向函数的指针。
  • 您是否在询问如何编写一个可行的函数,该函数可以作为比较器传递,您的讲师错误地使用非 const void * 参数进行编码,以使用名称作为比较的驱动力?我现在很好奇乔纳森的回答是针对什么问题,因为这显然不是这个话题的第一个牛仔竞技表演。编辑:found it
  • 是的!我需要一个单独的函数,它会提示输入名称并从 BST 中搜索和列出匹配的名称!对于每种情况,它很可能有几个匹配的名称。感谢您分解它
  • 那么在乔纳森的the question answered (in heavy depth) 和现在之间发生了什么变化?有什么你根本不明白的吗?
  • 是的,我只是不明白如何将他的答案实现到一个可以与我的代码一起使用的单独函数中。你能用不同的话向我解释一下吗?谢谢

标签: c debugging sorting search binary-search-tree


【解决方案1】:

按名称排序就像使用 strcmp function 按整数排序一样简单:

int strcmp ( const char * str1, const char * str2 );

如果字符串相等则返回 0,如果第一个字符串在词法上“更大”则返回 0,否则返回 -1。

您的compareStu 函数应该使用strcmp 来返回一个值。

【讨论】:

    猜你喜欢
    • 2014-04-30
    • 1970-01-01
    • 1970-01-01
    • 2020-06-22
    • 1970-01-01
    • 2017-09-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多