148. Sort List (java 给单链表排序)

题目:Sort a linked list in O(n log n) time using constant space complexity.

分析:给单链表排序,要求时间复杂度是O(nlogn),空间复杂度是O(1)。时间复杂度为O(nlogn)的排序算法有快速排序和归并排序,

          但是,对于单链表来说,进行元素之间的交换比较复杂,但是连接两个有序链表相对简单,因此这里采用归并排序的思路。

编码:

public ListNode sortList(ListNode head) {
        if(head == null || head.next == null)
            return head;
        //找到链表的中间节点,一快一慢两个指针
        ListNode fast = head;
        ListNode slow = head;
        ListNode pre = null; //记录第一部分的最后一个节点
        //将单链表划分为两部分
        while(fast != null && fast.next != null){
            fast = fast.next.next;
            pre = slow;
            slow = slow.next;
        }
        
        //将两部分分割开
        if(pre != null)
           pre.next = null;
        
        //分别对两部分递归排序
        ListNode l1 = sortList(head);
        ListNode l2 = sortList(slow);
        
        return merge(l1,l2); //归并
        
    }
    
    //归并两个有序序列
    public ListNode merge(ListNode l1,ListNode l2){
        if(l1 == null)
           return l2;
        if(l2 == null)
           return l1;
        ListNode l = new ListNode(-1);
        ListNode newHead = l;
        while(l1 != null && l2 != null){ 
            if(l1.val < l2.val){
                newHead.next = l1; //这里利用单链表的性质,不使用额外的空间,使得空间复杂度为O(1)
                l1 = l1.next;
                newHead = newHead.next;
            } else {
                newHead.next = l2;
                l2 = l2.next;
                newHead = newHead.next;
            }
        }
        
        if(l1 != null)
           newHead.next = l1;
        if(l2 != null)
           newHead.next = l2;
        return l.next;
    }

 

posted @ 2016-08-13 20:32  江湖凶险  阅读(772)  评论(0编辑  收藏  举报