您好我正在编写一个管理学生列表的程序,我正在使用列表,每个元素都是这样描述的:
struct student
{
char lastname[50];
char name[50];
char date_of_birth[50];
char height[50];
struct student *next;
};
struct student *root=0; //this is the root node
这就是我将元素添加到列表中的方式:
void add_element(struct student **root, char lastname[50], char name[50], char date_of_birth[50], char height[50])
{
if(*root == 0)
{
*root = malloc(sizeof(struct student));
strcpy((*root)->lastname,lastname);
strcpy( (*root)->name,name);
strcpy( (*root)->date_of_birth,date_of_birth);
strcpy( (*root)->height,height);
(*root)->next = 0;
}
else
{
add_element(&(*root)->next,lastname,name,date_of_birth,height);
}
}
我还写了2个函数,一个用于从一个文件中读取,另一个用于写入文件,该文件包含所有学生,一切正常但我需要一个函数按字母顺序排序所有元素的姓氏,我试着写一个,但它不起作用,它一直在崩溃。
我尝试过很多东西而且他们没有工作,这是一次尝试,而且它不起作用: - (
请帮帮我
void sort(struct student *head)
{
struct student **current;
struct student *tmp;
for(current = &head ; *current !=NULL ; current = (*current)->next)
{
if((*current)->next == NULL)
{
break;
}
switch(strcmp((*current)->lastname,(*current)->next->lastname))
{
case 0:
{
printf("user not valid");
break;
}
case 1:
{
tmp = *current;
*current = (*current)->next;
(*current)->next = tmp;
break;
}
}
}
}
答案 0 :(得分:1)
在包含评论备注以纠正建议的源代码之后,对链表进行排序的算法缺少一些步骤。至少,要对链表进行排序,必须有两个循环。对于两个嵌套循环,struct student **current
访问使用的选择将很复杂。
这是使用优化的qsort()
函数的另一个强大的排序函数。
第1步 - 在显示函数之前,要对列表进行排序,应修改root
指针。
第一种方法,通过发送地址用于
add_element()
指针。
void sort(struct student **root)
{
...
}
第二种方法,返回修改后的
root
。
struct student *sort(struct student *root)
{
...
return (root);
}
第2步 - 使用sort()
快速排序功能的qsort()
功能。
该方法分配一个临时的指针数组,以便对一个固定大小的元素进行排序。
struct student *
数组后,使用循环填充数组到链表的每个项目; qsort()
调用node_compare()
函数(请参阅下一步); struct student *next
的值(第一个是*root
,最后一个指向NULL)来恢复带有排序指针的链表。struct student *
; 就是这样。
//
void sort(struct student **root)
{
struct student *tmp;
struct student **array;
int i,icount;
// number of nodes to be sorted
for(tmp = *root,icount = 0;tmp!=NULL;tmp = tmp->next,icount++);
if (icount<2) {
// no sort needed
return;
}
// allocate an array of pointers
array = (struct student **)malloc(icount*sizeof(struct student *));
// push linked-list into array of pointers
for(tmp = *root,icount = 0;tmp!=NULL;tmp = tmp->next,icount++) {
array[icount]=tmp;
}
// quicksort using node_compare() customized function
qsort(array, icount, sizeof(struct student *), node_compare);
// pop linked-list from array of pointers
*root = array[0];
(*root)->next = NULL;
for(tmp = *root,i = 1;i<icount;i++) {
tmp->next = array[i];
array[i]->next = NULL;
tmp = tmp->next;
}
// free the allocated array of pointer
free(array);
}
//
第3步 - node_compare()
所需的比较函数qsort()
。
该函数应返回
strcmp()
所做的签名比较。
int node_compare(const void * a, const void * b)
{
// restore node pointers
struct student *node_a = *((struct student **)a);
struct student *node_b = *((struct student **)b);
if (node_b==NULL) return (-1); // force 'node_a'
if (node_a==NULL) return (+1); // force 'node_b'
// use the strcmp() function
return (strcmp(node_a->lastname,node_b->lastname));
}
增强 - 因为add_element()
正在使用不符合长链接列表的递归调用,所以这是一个非常简单的非递归算法。
如果递归算法将大小限制为几个世纪 元素,建议的元素已经测试了100,000个元素(40Mb linked-list),随机生成并排序。
void add_element(struct student **root, char lastname[50], char name[50], char date_of_birth[50], char height[50])
{
struct student **current;
for(current = root; *current !=NULL ; current = &((*current)->next));
*current = (struct student *)malloc(sizeof(struct student));
strcpy((*current)->lastname,lastname);
strcpy( (*current)->name,name);
strcpy( (*current)->date_of_birth,date_of_birth);
strcpy( (*current)->height,height);
(*current)->next = NULL;
}