[英]Sort in alphabetical order a List in c
嗨,我正在編寫一個管理學生名單的程序,我正在使用名單,每個元素的描述如下:
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;
}
}
}
}
在包含注釋的注釋以糾正建議的源代碼之后,對鏈表進行排序的算法缺少一些步驟。 至少,要對鏈接列表進行排序,必須要有兩個循環。 對於兩個嵌套循環, struct student **current
訪問所使用的選擇將很復雜。
這是使用優化的qsort()
函數的另一個強大的排序函數。
步驟1-在顯示功能之前,要對列表進行排序,必須修改root
指針。
第一種方法,通過發送指針的地址用於
add_element()
。
void sort(struct student **root)
{
...
}
第二種方法,返回修改后的
root
。
struct student *sort(struct student *root)
{
...
return (root);
}
第2步 -使用qsort()
quicksort函數的sort()
函數。
該方法分配一個臨時的指針數組,以便對固定大小的元素進行排序。
struct student *
數組之后,使用循環對鏈表的每個項目進行填充; node_compare()
調用qsort()
函數(請參閱下一步); struct student *next
(第一個是*root
,最后一個指向NULL)的值來恢復帶有排序指針的鏈表。 struct student *
的臨時數組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()
所需的比較函數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鏈表)進行了測試,並隨機生成並排序。
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;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.