如何按名称(字符串)搜索和排序BST?按队列打印并缩进?

时间:2014-03-23 01:09:58

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

我必须编写一个程序,将.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;

读取文件和插入函数工作正常,但我不知道如何按名称(字符串)实现搜索。 strcmp会工作吗?如果是这样,我将如何使用它?我有一个工作搜索功能,但它已经过优化,可以搜索id(整数),但它不能用于字符串。 以下是搜索功能的一部分:

/*  ===================== _retrieve =====================
Searches tree for node containing requested key
and returns its data to the calling function.
   Pre     _retrieve passes tree, dataPtr, root
           dataPtr is pointer to data structure
              containing key to be located
   Post    tree searched; data pointer returned
   Return  Address of data in matching node
           If not found, NULL returned
 */
 static void* _retrieve (BST_TREE* tree,
              void* dataPtr, NODE* root)
 {
if (root){
     if (tree->compare(dataPtr, root->dataPtr) < 0)
         return _retrieve(tree, dataPtr, root->left);
     else if (tree->compare(dataPtr, root->dataPtr) > 0)
         return _retrieve(tree, dataPtr, root->right);
     else
         // Found equal key
         return root;
}  // if root
else
    // Data not in tree
    return NULL;
 }// _retrieve

另外,我如何对BST进行排序?特别是我如何按字符串排序,它由2个部分(名字和姓氏)组成?我应该只按第一个字符排序吗?我正在考虑以某种方式删除姓氏部分,并且因为我的老师并没有真正说明她希望如何完成,所以只能通过名字来查看。她从未告诉过我们有关按非整数值排序BST的信息,因此我输了。

还有一件事是这个树需要打印:level(队列),缩进列表和仅叶子。     缩进打印列表示例:

  1.50
   2.70
     3.80
     3.90
   2.60
     3.30

我真的很感激有关实施这些任务的任何建议。

谢谢

1 个答案:

答案 0 :(得分:0)

不,strcmp()不会直接工作,因为比较器传递了两个STUDENT *值(伪装成void *。所以你必须编写一个比较器来解压缩指针,然后调用strcmp()

int cmp_by_name(const void *v1, const void *v2)
{
    const STUDENT *s1 = (STUDENT *)v1;
    const STUDENT *s2 = (STUDENT *)v2;

    return strcmp(s1->name, s2->name);
}

会有人说演员阵容不是绝对必要的。将会有人观察到在strcmp()的调用中使用稍微复杂的表达式可以省略变量。但是,如果您决定需要比较GPA或ID号,那么拥有局部变量将更加清晰。编译器可能会将这些变量作为常规优化消除,因此以清晰为代价手动执行此操作就是“过早优化”的情况。

由于您使用的模板在比较器类型的声明中不包含const,因此您可能必须从函数定义行中省略const


你不需要对BST进行分类;数据已经按排序顺序存储。您可以按照排序顺序将其打印出来,并按顺序遍历树。


您只需将compare的{​​{1}}元素设置为BST_TREE

cmp_by_name

然后使用BST_TREE root = { 0, cmp_by_name, 0 }; 作为树的根调用您的函数。这不是您提供的比较功能。您应该使用单个比较函数构建和搜索树;在不同时间使用不同的比较器会导致混乱。

如果您使用的是ISO 8859代码集(例如8859-15),或者您正在使用Unicode,则不需要删除逗号。逗号的排序早于任何字母,因此这些名称按顺序排列:

&root

您遇到问题的唯一时间是数据不一致:

Lee, James
Lee, Kirk
Leeds, Shaw
Left, Right

排序顺序;你可能想要逆转订单。