148. 排序链表*【力扣】

题意理解

对一个链表排序,要求时间复杂度O(nlogn)

问题分析

用归并 + 快慢指针

归并的套路是先分块排序,再合并排序。用快慢指针分块。

其他

https://blog.csdn.net/Scarlett_Guan/article/details/79435552

链接

    ListNode* sortList(ListNode* head) {
        if (!head || !head -> next) {    //空链表或1个结点链表
            return head;    //直接返回链表
        }  
        /*
        ListNode* pp = head;
        while (pp) {
            cout << pp -> val;
            pp = pp -> next;
        }
        cout << endl;
        */
        ListNode *slow = head;    //慢指针,初始化指向第一个结点
        ListNode *fast = head;    //快指针,初始化指向第一个结点
        ListNode *pre = head;    //指向慢指针前一个位置
        while (fast && fast -> next) {    //向后走两步,(已经判断可以走)
            pre = slow;    //保留慢指针前一个结点
            slow = slow -> next;    //慢指针走一步
            fast = fast -> next -> next;    //快指针走两步
        }
        pre -> next = nullptr;    //慢指针来分隔
        head = sortList (head);    //递归排序前半链表
        slow = sortList (slow);    //递归排序后半链表
        return mergeList (head, slow);    //合并前后半个链表
    }
    ListNode* mergeList (ListNode* head1, ListNode* head2) {
        ListNode* dummy = new ListNode(0);    //虚拟头结点,方便合并(key)
        ListNode* p = dummy;    //后移指针
        while (head1 && head2) {    //链表双指针都存在
            if (head1 -> val <= head2 -> val) {    //前链表小
                p -> next = head1;    //前链表当前指针结点连上合并后的结点
                head1 = head1 -> next;    //前链表后移
            }
            else {    //否则
                p -> next = head2;    //后链表当前指针结点连上合并和的结点
                head2 = head2 -> next;    //后链表后移
            }
            p = p -> next;    //合并后的链表后移
        }
        if (head1) {    //如果前链表还存在
            p -> next = head1;    //连上合并后的链表
        }
        if (head2) {    //如果后链表还存在
            p -> next = head2;    //连上合并后的链表
        }
        return dummy -> next;    //虚拟头结点去掉后的链表返回
    }

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值