首页 > 解决方案 > C语言上的排序链表

问题描述

我这里有个问题,我想用 3 个数据输入对我的链接列表进行排序,但是当我执行这个时,只有 1 个数据被排序。我试图将要替换的临时节点映射到新节点,但映射仅适用于num_id数据。哪里

例如:

  1. 数据需要排序
21507 - John - Mathematics
21477 - Andrew - Biology
21905 - James - Physics
21322 - Sophia - Chemistry
  1. 预期结果
21322 - Sophia - Chemistry
21477 - Andrew - Biology
21507 - John - Mathematics
21905 - James - Physics
  1. 我得到了什么
21322 - John - Mathematics
21477 - Andrew - Biology
21507 - James - Physics
21905 - Sophia - Chemistry

这是我的脚本:

节点

struct nodes{
    int num_id;
    char name[30], lesson[30];
    struct nodes *link;
}*head, *current, *temp, *tail;

排序链表

void linked_list_sorted() {
    struct nodes *node, *temp_sorted;
    int temp_sortedvar_num_id, count_data=0;
    char temp_sortedvar_name[30], temp_sortedvar_lesson[50];
    node = head;
    while(node != NULL)
    {
        temp_sorted=node; 
        while (temp_sorted->link !=NULL)
        {
            if(temp_sorted->num_id > temp_sorted->link->num_id)
                {
                temp_sortedvar_num_id = temp_sorted->num_id;
                temp_sorted->num_id = temp_sorted->link->num_id;
                temp_sorted->link->num_id = temp_sortedvar_num_id;
                }
            else if(temp_sorted->name > temp_sorted->link->name)
                {
                strcpy(temp_sortedvar_name, temp_sorted->name);
                strcpy(temp_sorted->name, temp_sorted->link->name);
                strcpy(temp_sorted->link->name, temp_sortedvar_name);
                }
            else if(temp_sorted->lesson > temp_sorted->link->lesson)
                {
                strcpy(temp_sortedvar_lesson, temp_sorted->lesson);
                strcpy(temp_sorted->lesson, temp_sorted->link->lesson);
                strcpy(temp_sorted->link->lesson, temp_sortedvar_lesson);
                }
            temp_sorted = temp_sorted->link;
        }
        node = node->link;
    }
    temp_sorted = head;
    while(temp_sorted != NULL) {
        count_data++;
        printf("%d. %d - %s - %s\n", count_data, temp_sorted->num_id, temp_sorted->name, temp_sorted->lesson);
        temp_sorted = temp_sorted->link;
    }
}

最后,这是我将数据推送到链接列表的脚本:

void push_data (int nim, char name[], char lesson[]) {
    // Push Step (Head, Mid, Tail)
    current = (struct nodes*)malloc(sizeof(struct nodes));
    current->nim = nim;
    strcpy(current->name, name);
    strcpy(current->lesson, lesson);

    if (head == NULL){
        head = tail = current;
    } else if (current->nim < head->nim) {
        current->link = head;
        head = current;
    } else{
        tail->link = current;
        tail = current;
    }
}

标签: csortinglinked-listsortedlist

解决方案


您的函数中的问题之一是它相互独立地sorted交换节点的不同成员。将成员与下一个交换的条件与对 进行相同操作的条件不同。然而,这些应该永远在一起!所以要么你不应该交换任何东西,要么你应该交换所有成员。num_idname

由于您的代码负责将新数据推送到列表中,为什么不确保将新节点放置在列表中的排序位置?那你就不需要了sorted。事实上,当一个节点恰好小于当前头节点的节点时,您push_data已经有将节点放在列表前面的逻辑。num_id如果您对其他节点执行相同操作,您将始终对列表进行排序:

void push_data (int num_id, char name[], char lesson[]) {
    // Use a local variable for referencing the new node:
    struct nodes *nodeNode = (struct nodes*)malloc(sizeof(struct nodes));
    nodeNode->num_id = num_id;
    strcpy(nodeNode->name, name);
    strcpy(nodeNode->lesson, lesson);

    if (head == NULL){
        head = tail = nodeNode;
    } else if (num_id <= head->num_id) {
        nodeNode->link = head;
        head = newNode;
    } else if (num_id >= tail->num_id) { // Add this condition
        tail->link = newNode;
        tail = newNode;
    } else { // Add this case:
        // Look for the insertion point, assuming list is sorted.
        // Use a local variable for current; not a member
        struct nodes *current = head;
        while (num_id > current->link->num_id) {
            current = current->link;
        }
        newNode->link = current->link;
        current->link = newNode;
    }
}

现在您的列表将始终被排序。


推荐阅读