簡體   English   中英

按字母順序排序c中的列表

[英]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()函數。

該方法分配一個臨時的指針數組,以便對固定大小的元素進行排序。

  1. 第一個循環對於知道要排序的指針的數量是必要的(如果小於2,則不需要排序);
  2. 在分配了struct student *數組之后,使用循環對鏈表的每個項目進行填充;
  3. 通過使用定制的比較函數node_compare()調用qsort()函數(請參閱下一步);
  4. 通過強制struct student *next (第一個是*root ,最后一個指向NULL)的值來恢復帶有排序指針的鏈表。
  5. 釋放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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM