leetcode之链表类之链表排序-----147/148. 链表快速排序 链表插入排序

1、OJ148链表快速排序

和数组的快排完全相同,dfs分治,过程也一样,唯一多了的是,在计算出partition点j后,对后半部的递归需要做"partition点和end点是否已经相同"的判断,这是在end点已经是极大/小值时,会导致partition点j也走到end点,在数组快排可以通过"if (start >= end)"过滤,对于单链表则必须在这里提前判断出来,避免进行起点在终点后面的递归

快排的最大好处是空间复杂度符合题意的常数空间复杂度,而归并则需要O(N)空间复杂度,堆本身是数组实现,对链表进行堆排本质上是重载比较运算符,但也需要O(N)空间复杂度。


代码:

    ListNode *findtail (ListNode *head) {
        while (head && head->next) {
            head = head->next;
        }
        
        return head;
    }
    
    void qsort (ListNode *head, ListNode *tail) {
        if (head == tail) {
            return;
        }
        
        int flagval = tail->val;
        ListNode *j = head, *prev = j, *rawst = head;
        while (head && head != tail) {
            if (head->val < flagval) {
                int tmp = head->val;
                head->val = j->val;
                j->val = tmp;
                prev = j;
                j = j->next;
            }
            head = head->next;
        }
        
        tail->val = j->val;
        j->val = flagval;
        
        head = rawst;        
        qsort(head, prev);
        if (j != tail) {
            qsort(j->next, tail);
        }
    }
    
    ListNode* sortList(ListNode* head) {
        if (!head || !head->next) {
            return head;
        }
        
        ListNode *tail = findtail(head);
        qsort(head, tail);
        return head;
    }


2、OJ147链表插入排序

虽然是插入排序的思想,但是做法和数组插入排序比较不同,核心思路是,将链表分为已排序和未排序两部分开的链表,已排序部分初始只有首元素一个节点,未排序的部分不断的按value大小,插入到已排序部分。

OJ147代码:

class Solution {
public:
    ListNode* insertionSortList(ListNode* head) {
        if (!head || !head->next) {
            return head;
        }
        
        ListNode *sorted = head, *unsorted = head->next;
        sorted->next = nullptr;
        
        while (unsorted) {
            ListNode *cur = unsorted;
            unsorted = unsorted->next;
            
            if (sorted->val > cur->val) {
                cur->next = sorted;
                sorted = cur;
            } else {
                ListNode *p = sorted, *q = sorted->next;
                while (q && q->val < cur->val) {
                    p = q;
                    q = q->next;
                }
                
                if (q) {
                    p->next = cur;
                    cur->next = q;
                } else {
                    p->next = cur;
                    cur->next = nullptr;
                }
            }
        }
        
        return sorted;
    }
};

3、链表归并排序

包括两个链表的归并排序和多个链表的归并排序,这部分虽然也属于排序,但更属于另一类基于归并的相关题,在此不描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值