我必须编写一个程序,将.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
我真的很感激有关实施这些任务的任何建议。
谢谢
答案 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
排序顺序;你可能想要逆转订单。