【leetcode 单链表归并排序】Sort List

1、题目

Sort a linked list in O(n log n) time using constant space complexity.
OJ地址:https://oj.leetcode.com/problems/sort-list/

2、分析

题目要求时间复杂度为O(nlogn),空间复杂度为O(1),满足要求的排序算法有快速排序,归并排序,堆排序.....
一般来说,单链表排序用归并,双链表排序用快排,代码比较容易写。
本题是单链表,用归并会比较容易,并且利用了另一道题Merge Two Sorted Lists的代码,见我的另一篇笔记:http://blog.csdn.net/u012162613/article/details/40904163

3、归并排序代码

<span style="font-size:18px;">/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    /*归并排序*/
    ListNode *sortList(ListNode *head) {   
        if(!head || !head->next) return head;     //空或者只有一个元素,直接return
        ListNode dummy(-1);dummy.next=head;
        ListNode *pslow=&dummy,*pfast=&dummy;//快慢指针,找出链表的中间节点,然后对左右两个子链表递归地调用归并排序
        while(pfast&&pfast->next)
        {
            pslow=pslow->next;
            pfast=pfast->next->next;
        }
        ListNode *right_begin=pslow->next;
        pslow->next=nullptr;  //断开两段子链表
        ListNode *l1=sortList(dummy.next);
        ListNode *l2=sortList(right_begin);
        return mergeTwoLists(l1,l2);
    }
private:
    ListNode *mergeTwoLists(ListNode *l1, ListNode *l2) {  
        ListNode dummy(-1);  
        ListNode *head1=l1,*head2=l2,*tail=&dummy;  
        while(head1!=nullptr && head2!=nullptr)  
        {  
            if(head1->val<head2->val) {tail->next=head1;head1=head1->next;}  
            else                      {tail->next=head2;head2=head2->next;}  
            tail=tail->next;  
        }  
        if(head1==nullptr)   tail->next=head2;  
        if(head2==nullptr)   tail->next=head1;  
    return dummy.next;  
    }  
};</span>


4、快速排序代码(有bug)

我试着写成快排,处理起来很繁琐,凌乱,代码难看,我都不知道自己在写什么........最后不知道哪里有bug,调到不想调
<span style="font-size:18px;">/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode *sortList(ListNode *head) {
        if(!head) return head;
        ListNode *tail=head;
        while(tail->next) tail=tail->next; 
        return quicksort(head,tail);
    }
private:
    ListNode *quicksort(ListNode *head,ListNode *mid)
    {   
        if(head==mid) return head; 
        ListNode dummy(-1);dummy.next=head;
        ListNode *i=&dummy,*j=dummy.next,*pre_j=&dummy;
        while(j!=mid)
        {
           if(j->val>=mid->val)  {pre_j=j;j=j->next;}
           else {
               ListNode *inext=i->next;
               ListNode *inextnext=inext->next;
               ListNode *jnext=j->next;
               i->next=j;
               j->next=inextnext;
               pre_j->next=inext;
               inext->next=jnext;
               
               i=i->next;
               pre_j=j;
               j=j->next;
               }
           
        }
        if(i->next==mid)  {quicksort(dummy.next,i);}
        else
        {
        pre_j->next=mid->next;
        mid->next=i->next;
        i->next=mid;
        if(i==&dummy) {quicksort(mid->next,pre_j);}
        else
             {
                  quicksort(mid->next,pre_j);
                  quicksort(dummy.next,i);
             }
        }
        return dummy.next;
    }
};</span>




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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值