问题
I have to write a program that reads a .txt file into the tree and then it allows to perform specific operations with it. I'm stuck on the part where I need to sort tree by names and search by name as well, any input would be awesome. So, my input file is in the format :
3800 Lee, Victor; 2.8
3000 Brown, Joanne; 4.0
So, my binary tree is in the format of:
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;
Read file and insert functions are working just fine, but I dont know how to implement search by name(string). Will strcmp work? If so, how would I use it? I have a working search function, but it's optimized to search for id(integer) and it doesn't work with strings. Here is a part of search 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) < 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
Also, how do I sort the BST? Especially how would I sort it by name which is string and consists of 2 parts (first and last name)? Should I sort it only by the first character? I was thinking of dropping the last name part somehow and making it easier to look only by first names since my teacher didn't really specify how she wants this done. She never told us about sorting BST by non-integer values, therefore I'm lost.
One more thing is that this tree would need to be printed by: level(queue), as indented list and by leaves only. Example of indented printed list:
1.50
2.70
3.80
3.90
2.60
3.30
I would really appreciate any suggestions on implementing those tasks.
Thank You
回答1:
No, strcmp()
won't work directly, because the comparator is passed two STUDENT *
values (disguised as void *
. So you will have to write a comparator that unpackages the pointers and then calls 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);
}
There will be those who say the casts are not absolutely necessary. There will be those who observe that the variables could be omitted by using slightly more complex expressions in the call to strcmp()
. However, if you decide that you need to compare on GPA or ID number too, then having the local variables will be cleaner. The compiler will probably eliminate the variables anyway as a routine optimization, so doing that manually at the cost of clarity is a case of 'premature optimization'.
Because the templates you are working with don't include const
in the declaration of the comparator type, you may have to omit const
from the function definition line.
You don't need to sort the BST; the data is already stored in a sorted order. You can print it out in sorted order with an in-order traversal of the tree.
You simply set the compare
element of the BST_TREE
to cmp_by_name
:
BST_TREE root = { 0, cmp_by_name, 0 };
You then call your functions with &root
as the root of the tree. This is instead of the comparison function you were provided with. You should build and search the tree with a single comparison function; using different comparators at different times will cause chaos.
You don't need to zap the comma if you're using an ISO 8859 code set such as 8859-15, or if you're using Unicode. The comma sorts earlier than any letters, so these names are in order:
Lee, James
Lee, Kirk
Leeds, Shaw
Left, Right
The only time you'd have problems is if the data is not consistent:
Lee James
Lee, Brady
That's the sorted order; you'd probably want the order reversed.
来源:https://stackoverflow.com/questions/22585793/how-to-search-and-sort-bst-by-namestring-printing-by-queue-and-indented