Data Structures and Algorithms for Sorted Lists

                                              sorted linked list

                                                                  ReferenceLeetcode-148

1. Merge sort linked list

1. Method 1: Top-down merge sort

    Proceed as follows:

  • Find the midpoint of the linked list and split the linked list into two sub-linked lists;

  • Merge and sort the two sublists;

  • Repeat the first two steps for the two sub-lists;

    The code reference is as follows:

#include <iostream>
using namespace std;

struct ListNode {
    int val;
    ListNode *next;
    ListNode() : val(0), next(nullptr) {}
    ListNode(int x) : val(x), next(nullptr) {}
    ListNode(int x, ListNode *next) : val(x), next(next) {}
};

class Solution {
public:
    ListNode* sortList(ListNode* head) {
        return sortList(head, nullptr);
    }

    ListNode* sortList(ListNode* head, ListNode* tail) {
        if (head == nullptr) { // 为空结点返回
            return head;
        }
        if (head->next == tail) { // 只剩一个结点后返回
            head->next = nullptr;
            return head;
        }
        /* 双指针法找到中间结点 */
        ListNode* slow = head, *fast = head;
        while (fast != tail) {
            slow = slow->next;
            fast = fast->next;
            if (fast != tail) {
                fast = fast->next;
            }
        }
        ListNode* mid = slow;
        /* 合并两个子链表 */
        return merge(sortList(head, mid), sortList(mid, tail));
    }

    /* 合并两个子链表的方法 */
    ListNode* merge(ListNode* head1, ListNode* head2) {
        ListNode* dummyHead = new ListNode(0);
        ListNode* temp = dummyHead, *temp1 = head1, *temp2 = head2;
        while (temp1 != nullptr && temp2 != nullptr) {
            if (temp1->val <= temp2->val) {
                temp->next = temp1;
                temp1 = temp1->next;
            } else {
                temp->next = temp2;
                temp2 = temp2->next;
            }
            temp = temp->next;
        }
        if (temp1 != nullptr) {
            temp->next = temp1;
        } else if (temp2 != nullptr) {
            temp->next = temp2;
        }
        return dummyHead->next;
    }
};

int main() {
    Solution sol;
    ListNode *l1 = new ListNode(-1);
    ListNode *l2 = new ListNode(5);
    ListNode *l3 = new ListNode(3);
    ListNode *l4 = new ListNode(4);
    ListNode *l5 = new ListNode(0);

    l1->next = l2;
    l2->next = l3;
    l3->next = l4;
    l4->next = l5;

    sol.sortList(l1);

    return 0;
}

    The time complexity of the above algorithm is O(n logn), and the space complexity is O(logn), where n is the length of the linked list.

2. Method 2: Bottom-up merge sort

    The specific method is as follows:

  • Split the linked list into sub-linked lists with a length of subLength, and merge every two sub-linked lists;

  • The length of subLength changes to [1, 2, 4, ...], each round is twice the previous round, repeat the above steps;

    The code example is as follows:

#include <iostream>
using namespace std;

struct ListNode {
    int val;
    ListNode *next;
    ListNode() : val(0), next(nullptr) {}
    ListNode(int x) : val(x), next(nullptr) {}
    ListNode(int x, ListNode *next) : val(x), next(next) {}
};

class Solution {
public:
    ListNode* sortList(ListNode* head) {
        if (head == nullptr) {
            return head;
        }
        /* 计算链表的长度 */
        int length = 0;
        ListNode* node = head;
        while (node != nullptr) {
            length++;
            node = node->next;
        }

        ListNode* dummyHead = new ListNode(0, head);
        for (int subLength = 1; subLength < length; subLength <<= 1) { // subLength左移1位,相当于subLength*2
            ListNode* prev = dummyHead, *curr = dummyHead->next;
            while (curr != nullptr) {
                ListNode* head1 = curr;
                for (int i = 1; i < subLength && curr->next != nullptr; i++) { // 根据subLength来更新curr,以此获得head2的位置
                    curr = curr->next;
                }
                ListNode* head2 = curr->next;
                curr->next = nullptr; // 断开链表,形成head1子链表
                curr = head2;
                for (int i = 1; i < subLength && curr != nullptr && curr->next != nullptr; i++) { // 同上
                    curr = curr->next;
                }
                ListNode* next = nullptr;
                if (curr != nullptr) { // 获取next指针,并且断开链表,形成head2子链表
                    next = curr->next;
                    curr->next = nullptr;
                }
                ListNode* merged = merge(head1, head2); // 合并两个子链表
                prev->next = merged;
                /* 更新prev、next指针 */
                while (prev->next != nullptr) {

                    prev = prev->next;
                }
                curr = next;
            }
        }
        return dummyHead->next;
    }

    /* 合并两个有序链表 */
    ListNode* merge(ListNode* head1, ListNode* head2) {
        ListNode* dummyHead = new ListNode(0);
        ListNode* temp = dummyHead, *temp1 = head1, *temp2 = head2;
        while (temp1 != nullptr && temp2 != nullptr) {
            if (temp1->val <= temp2->val) {
                temp->next = temp1;
                temp1 = temp1->next;
            } else {
                temp->next = temp2;
                temp2 = temp2->next;
            }
            temp = temp->next;
        }
        if (temp1 != nullptr) {
            temp->next = temp1;
        } else if (temp2 != nullptr) {
            temp->next = temp2;
        }
        return dummyHead->next;
    }
};

int main() {
    Solution sol;
    ListNode *l1 = new ListNode(-1);
    ListNode *l2 = new ListNode(5);
    ListNode *l3 = new ListNode(3);
    ListNode *l4 = new ListNode(4);
    ListNode *l5 = new ListNode(0);

    l1->next = l2;
    l2->next = l3;
    l3->next = l4;
    l4->next = l5;

    return 0;
}

    The sorting process is shown in the figure below:

first round:

second round:

Third round:

    Its time complexity is O(n logn) and space complexity is O(1), where n is the length of the linked list.

Guess you like

Origin blog.csdn.net/hu853712064/article/details/130543423