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

我必须编写一个程序,将.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会工作吗? 如果是这样,我将如何使用它? 我有一个工作搜索function,但它优化搜索id(整数),它不适用于字符串。 这是搜索function的一部分:

 /* ===================== _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) 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 

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

谢谢

不, 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进行排序; 数据已经按排序顺序存储。 您可以按照排序顺序将其打印出来,并按顺序遍历树。


您只需将BST_TREEcompare元素设置为cmp_by_name

 BST_TREE root = { 0, cmp_by_name, 0 }; 

然后使用&root作为树的根来调用函数。 这不是您提供的比较function。 您应该使用单个比较函数构建和搜索树; 在不同时间使用不同的比较器会导致混乱。

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

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

您遇到问题的唯一情况是数据不一致:

 Lee James Lee, Brady 

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