c语言编程笔录

首页 >   > 笔记大全

笔记大全

c语言 链表 排序

更新时间:2024-01-22

问题描述

这个问题涉及使用C语言编写代码来对链表进行排序。我们需要实现一个函数,该函数将按升序对链表进行排序,并返回排序后的链表。

解决方案

首先,我们需要定义一个链表节点的数据结构,其中包含一个值和一个指向下一个节点的指针。

struct ListNode {
    int val;
    struct ListNode *next;
};

接下来,我们可以编写一个排序函数,使用插入排序的算法来对链表进行排序。

插入排序的基本思想是将链表分为已排序和未排序两部分。我们从未排序部分取出一个节点,然后在已排序部分找到合适的位置插入该节点,然后继续此过程直到遍历完所有节点。

struct ListNode* insertionSortList(struct ListNode* head) {
    if (head == NULL || head->next == NULL) return head;
    
    struct ListNode* dummy = malloc(sizeof(struct ListNode));
    dummy->val = INT_MIN;
    dummy->next = head;
    
    struct ListNode* prev = dummy;
    struct ListNode* curr = head;
    
    while (curr != NULL) {
        if (curr->val < prev->val) {
            struct ListNode* node = dummy;
            while (node->next != NULL && node->next->val < curr->val) {
                node = node->next;
            }
            
            prev->next = curr->next;
            curr->next = node->next;
            node->next = curr;
            curr = prev;
        }
        
        prev = curr;
        curr = curr->next;
    }
    
    struct ListNode* newHead = dummy->next;
    free(dummy);
    return newHead;
}

代码分析

在插入排序函数中,我们先创建一个哑节点(dummy),它的值为INT_MIN,并将其next指针指向链表的头节点。

然后,我们使用两个指针prev和curr来遍历链表。prev指针指向已排序部分的最后一个节点,curr指针指向未排序部分的第一个节点。

如果curr节点的值小于prev节点的值,表示需要将curr节点插入到已排序部分的正确位置。我们使用一个指针node来遍历已排序部分,直到找到合适的插入位置。

完成插入操作后,我们将prev指针和curr指针向后移动,并继续下一轮循环,直到遍历完所有节点。

最后,我们返回dummy节点的下一个节点作为排序后的链表头节点。

总结

通过实现这个排序函数,我们可以对链表进行排序。使用插入排序算法,我们可以将时间复杂度控制在O(n^2)级别,并且不需要额外的空间。

需要注意的是,这个排序函数适用于普通的单向链表。如果链表较大或需要使用其他高效排序算法,可能需要考虑使用其他数据结构或算法。