1. 程式人生 > >147. 對鏈表進行插入排序

147. 對鏈表進行插入排序

ron 演示 head gif ini 分析 tps 輸入數據 turn

題目描述

對鏈表進行插入排序。

技術分享圖片
插入排序的動畫演示如上。從第一個元素開始,該鏈表可以被認為已經部分排序(用黑色表示)。
每次叠代時,從輸入數據中移除一個元素(用紅色表示),並原地將其插入到已排好序的鏈表中。

插入排序算法:

  1. 插入排序是叠代的,每次只移動一個元素,直到所有元素可以形成一個有序的輸出列表。
  2. 每次叠代中,插入排序只從輸入數據中移除一個待排序的元素,找到它在序列中適當的位置,並將其插入。
  3. 重復直到所有輸入數據插入完為止。

示例 1:

輸入: 4->2->1->3
輸出: 1->2->3->4

示例 2:

輸入: -1->5->3->4->0
輸出: -1->0->3->4->5

分析

跳過開頭已經有序的部分,對剩下的無序部分進行插入排序。但是時間復雜度還是很高。

貼出代碼

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) { val = x; }
 * }
 */
class Solution {
    public ListNode insertionSortList(ListNode head) {
        if(head == null || head.next == null){
             return head;
        }
        ListNode dummy = new ListNode(0), sorted = head;
        dummy.next = head;
        while(sorted != null && sorted.next != null && sorted.val < sorted.next.val){
            sorted = sorted.next;
        }
        while(sorted != null && sorted.next != null){
            ListNode curr = sorted.next;
            sorted.next = curr.next;
            ListNode pp = dummy, p = dummy.next;
            while(p != sorted && curr.val > p.val){
                pp = pp.next;
                p = p.next;
            }
            if(p != sorted || curr.val <= sorted.val){
                curr.next = p;
                pp.next = curr;
            }else{
                curr.next = sorted.next;
                sorted.next = curr;
                sorted = sorted.next;
            }
            curr = curr.next;
        }
        return dummy.next;
    }
}

147. 對鏈表進行插入排序