链表排序

排序这篇是数组排序,刷leetcode的时候碰到了链表排序,记录一下。

插入排序

class Solution {
public:
    ListNode* insertionSortList(ListNode* head) {
        if(!head) return nullptr;
        ListNode* dummy = new ListNode(0);
        
        while(head){
            ListNode* p = dummy;//每次重新定义p,相当于每次都是从头遍历
            while(p->next && p->next->val <= head->val) p = p->next;
            //此时p->next > head->val, p及前面的链表都小于head, head插在此处
            ListNode* tmp = head->next;
            head->next = p->next;
            p->next = head;
            head = tmp;//head后移一位,相当于i++
        }
        ListNode* ans = dummy->next;
        delete dummy;
        return ans;
    }
};

归并排序

// 迭代
class Solution {
public:
    ListNode* sortList(ListNode* head) {
        // get length of list
        int n = 0;
        ListNode* p = head;
        while (p) {
            p = p->next;
            n++;
        }
        ListNode dummy(0);
        dummy.next = head;
        // each time merge 2 -> 4 -> 8
        for (int i = 1; i < n; i *= 2) {
            // traverse all list
            auto cur = dummy.next;
            auto pre = &dummy;
            while (cur) {
                auto left = cur;
                // left->..., right->...
                auto right = cut(left, i);
                // right->..., cur->...
                cur = cut(right, i);
                // merge
                auto [begin, end] = merge(left, right);
                pre->next = begin;
                pre = end;
            }
        }
        return dummy.next;
    }
    // return tail->next
    ListNode* cut(ListNode* head, int length) {
        while (head && --length) {
            head = head->next;
        }
        if (!head) return nullptr;
        auto tmp = head->next;
        head->next = nullptr;
        return tmp;
    }
    
    tuple<ListNode*, ListNode*> merge(ListNode* a, ListNode* b) {
        ListNode dummy(0);
        ListNode* p = &dummy;
        while (a && b) {
            if (a->val <= b->val) {
                p->next = a;
                a = a->next;
            }
            else {
                p->next = b;
                b = b->next;
            }
            p = p->next;
        }
        while (a) {
            p->next = a;
            a = a->next;
            p = p->next;
        }
        while (b) {
            p->next = b;
            b = b->next;
            p = p->next;
        }
        return {dummy.next, p};
    }
};
// 递归
class Solution {
public:
    ListNode* sortList(ListNode* head) {
        return mergeSort(head);
    }

    ListNode* mergeSort(ListNode* head) {
        if (!head || !head->next) return head;
        ListNode* slow = head;
        ListNode* fast = head;
        while (fast->next && fast->next->next) {
            slow = slow->next;
            fast = fast->next->next;
        }
        // 此时slow为分割点
        ListNode* newHead = slow->next;
        slow->next = nullptr;

        ListNode* a = mergeSort(head);
        ListNode* b = mergeSort(newHead);
        
        return merge(a, b);
    }

    ListNode* merge(ListNode* a, ListNode* b) {
        ListNode dummy(0);
        ListNode* p = &dummy;
        while (a && b) {
            if (a->val <= b->val) {
                p->next = a;
                p = p->next;
                a = a->next;
            }
            else {
                p->next = b;
                p = p->next;
                b = b->next;
            }
        }
        if (a) {
            p->next = a;
        }
        if (b) {
            p->next = b;
        }
        return dummy.next;
    }
};

快速排序

class Solution {
public:
    ListNode* sortList(ListNode* head) {
        // each time select head
        // larger : head->next = larger;
        // smaller : smaller->next = head;
        if (!head || !head->next) return head;
        auto [left, right] = quickSort(head, nullptr);
        return left;
    }
    tuple<ListNode*, ListNode*> quickSort(ListNode* begin, ListNode* end) {
        if (begin == end) return {begin, end};
        ListNode* left = begin;
        ListNode* right = begin;
        int target = begin->val;
        ListNode* cur = begin->next;
        while (cur != end) {
            auto next = cur->next;
            // 头插
            if (cur->val < target) {
                cur->next = left;
                left = cur;
            }
            // 尾插
            else {
                right->next = cur;
                right = cur;
            }
            cur = next;
        }
        right->next = end; // 防止死循环
        auto [l1, r1] = quickSort(left, begin);
        auto [l2, r2] = quickSort(begin->next, end);
        // 链接
        left = l1;
        r1->next = l2;
        right = r2;

        return {left, right};
    }
};
posted @ 2020-11-21 17:35  miyanyan  阅读(179)  评论(0编辑  收藏  举报