刷題No24. sort-list(排序)(java)【鏈表】

題目:在O(n log n)的時間內使用常數級空間複雜度對鏈表進行排序。

思路:由於題目要求,時間複雜度要求爲O(n log n),所以,需要用歸併排序。

  • 找到鏈表的中間節點
  • 通過中間節點將鏈表1分爲2
  • 兩個鏈表進行比較,比較完之後進行合併。

代碼:

package com.company;

import java.util.List;

public class TestNo24 {
    //定義單鏈表
    static class ListNode{
        int val;
        ListNode next;
        ListNode(int x){
            val = x;
            next = null;
        }
        public String toString(){
            if(this.next == null){
                return String.valueOf(this.val);
            }
            return this.val + "->" + this.next.toString();
        }
    }
    public static void main(String[] args) {
        TestNo24 t = new TestNo24();
        ListNode head = new ListNode(4);
        head.next = new ListNode(5);
        head.next.next= new ListNode(7);
        head.next.next.next = new ListNode(9);
        head.next.next.next.next = new ListNode(10);
        head.next.next.next.next.next = new ListNode(1);
        head.next.next.next.next.next.next = new ListNode(2);
         // 下面是產生連續的鏈表
//        ListNode head = createTestLinkList();
//        ListNode newHead = new ListNode(13);
        //newHead.next = head;
        System.out.println(head);
        System.out.println(t.sortList(head));


    }
    private  static ListNode createTestLinkList(){
        ListNode head = new ListNode(0);
        ListNode curNode = head;
        for(int i = 0;i<10;i++){
            curNode.next = new ListNode(i);
            curNode = curNode.next;
        }
        return head;

    }
    public ListNode sortList(ListNode head) {
        if(head == null || head.next == null){
            return head;
        }
        ListNode mid = getMid(head);
        ListNode another ;
        if(mid == null){
            another = null;
        }else{
            //此時是兩個鏈表,從鏈表的中間節點分開,中間節點之前之後分別是一個鏈表
            another = mid.next;
            mid.next = null;
        }
        return mergeSortedList(sortList(head),sortList(another));
    }
    //合併兩個有序鏈表爲一個鏈表
    private ListNode mergeSortedList(ListNode first,ListNode second){
        if(first == null && second == null){
            return null;
        }
        if(first == null){
            return second;
        }
        if(second == null){
            return first;
        }
        //虛擬一個head的前綴節點
        ListNode pre = new ListNode(0);
        ListNode curNode = pre;

        ListNode cur1 = first;
        ListNode cur2 = second;
        while (cur1 != null && cur2 !=null){
            if(cur1.val <= cur2.val){
                curNode.next = cur1;
                cur1 = cur1.next;
            }else{
                curNode.next = cur2;
                cur2 = cur2.next;
            }
            curNode = curNode.next;
        }
        //處理剩下的節點元素
        if(cur1 != null){
            curNode.next = cur1;
        }else{
            curNode.next = cur2;
        }
        return pre.next;

    }
    //尋找鏈表的中間節點,使用快慢兩個指針
    private ListNode getMid(ListNode head){
        if(head == null || head.next == null){
            return head;
        }
        ListNode fast = head;
        ListNode slow = head;
        while (fast.next != null && fast.next.next !=null){
            fast = fast.next.next;
            slow = slow.next;
        }
        return slow;
    }
}

 

 

 

發佈了64 篇原創文章 · 獲贊 13 · 訪問量 4386
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章