按字母顺序排序c中的List

时间:2017-01-04 22:03:52

标签: c list sorting alphabetical alphabetical-sort

您好我正在编写一个管理学生列表的程序,我正在使用列表,每个元素都是这样描述的:

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;
            }
        }
    }
}

1 个答案:

答案 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()功能。

该方法分配一个临时的指针数组,以便对一个固定大小的元素进行排序。

  1. 第一个循环是必要的,以了解要排序的指针数量(如果低于2,则不需要排序);
  2. 分配struct student *数组后,使用循环填充数组到链表的每个项目;
  3. 使用自定义比较函数qsort()调用node_compare()函数(请参阅下一步);
  4. 通过强制struct student *next的值(第一个是*root,最后一个指向NULL)来恢复带有排序指针的链表。
  5. 释放临时数组struct student *;
  6. 就是这样。

    //
    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;
    }