LeetCode //C - 148. Sort List

148. Sort List

Given the head of a linked list, return the list after sorting it in ascending order.
 

Example 1:

LeetCode //C - 148. Sort List_第1张图片

Input: head = [4,2,1,3]
Output: [1,2,3,4]

Example 2:

LeetCode //C - 148. Sort List_第2张图片

**Input:**head = [-1,5,3,4,0]
Output: [-1,0,3,4,5]

Example 3:

Input: head = []
Output: []

Constraints:
  • The number of nodes in the list is in the range [ 0 , 5 ∗ 1 0 4 0, 5 * 10^4 0,5104].
  • − 1 0 5 < = N o d e . v a l < = 1 0 5 -10^5 <= Node.val <= 10^5 105<=Node.val<=105

From: LeetCode
Link: 148. Sort List


Solution:

Ideas:

1. Divide the List: The main idea is to split the list into two halves, sort each half, and then merge the sorted halves back together. This is a recursive approach.

2. Find the Middle:

  • findMiddle function is used to get the middle node of the list. This is done using the slow and fast pointer approach (sometimes called the hare and tortoise approach). The fast pointer moves two steps at a time, and the slow pointer moves one step at a time. When the fast pointer reaches the end of the list, the slow pointer is at the middle.
  • After finding the middle, the list is split into two by updating the next pointer of the node before the middle to NULL, effectively creating two separate lists.

3. Recursive Sort:

  • The sortList function calls itself recursively on each half of the list until it reaches a base case where the list is empty or has only one node (which is inherently sorted).
  • Once the base case is reached, the recursion starts to unwind, and the merge process begins.

4. Merge Sorted Lists:

  • The merge function takes two sorted lists as input and merges them into a single sorted list.
  • A dummy node is used to simplify the merging process. This node doesn’t contain any actual data and is only used as a starting point.
  • The function iterates over the two lists, comparing the current nodes’ values. The smaller node is attached to the current node in the merged list, and the pointer of the list containing that node is moved to the next node.
  • This process continues until one of the lists is exhausted. The remaining nodes from the non-empty list are then attached to the merged list, ensuring all nodes are included in the sorted order.

5. Completing the Merge:

  • As the recursion unwinds, smaller sorted portions of the list are merged together. This process continues until the entire list is sorted and merged.
Code:
/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */
struct ListNode* merge(struct ListNode* l1, struct ListNode* l2) {
    struct ListNode* dummy = (struct ListNode*)malloc(sizeof(struct ListNode));
    struct ListNode* current = dummy;
    while (l1 && l2) {
        if (l1->val < l2->val) {
            current->next = l1;
            l1 = l1->next;
        } else {
            current->next = l2;
            l2 = l2->next;
        }
        current = current->next;a
    }
    if (l1) current->next = l1;
    if (l2) current->next = l2;
    return dummy->next;
}

struct ListNode* findMiddle(struct ListNode* head) {
    struct ListNode* prev = NULL;
    struct ListNode* slow = head;
    struct ListNode* fast = head;
    while (fast && fast->next) {
        prev = slow;
        slow = slow->next;
        fast = fast->next->next;
    }
    if (prev) prev->next = NULL;  // Split the list into two halves
    return slow;
}

struct ListNode* sortList(struct ListNode* head) {
    if (!head || !head->next) return head; // Base case: if the list is empty or has only one node
    struct ListNode* mid = findMiddle(head);
    struct ListNode* left = sortList(head);
    struct ListNode* right = sortList(mid);
    return merge(left, right);
}

你可能感兴趣的:(LeetCode,leetcode,c语言,算法)