6.15 对链表进行插入排序【147】
6.15.1 题目描述
给定单个链表的头 head ,使用 插入排序 对链表进行排序,并返回 排序后链表的头 。
插入排序 算法的步骤:
- 插入排序是迭代的,每次只移动一个元素,直到所有元素可以形成一个有序的输出列表。
- 每次迭代中,插入排序只从输入数据中移除一个待排序的元素,找到它在序列中适当的位置,并将其插入。
- 重复直到所有输入数据插入完为止。
下面是插入排序算法的一个图形示例。部分排序的列表(黑色)最初只包含列表中的第一个元素。每次迭代时,从输入数据中删除一个元素(红色),并就地插入已排序的列表中。
对链表进行插入排序。
6.5.2 方法一:从前往后找插入点
class Solution {
public ListNode insertionSortList(ListNode head) {
if (head == null) {
return head;
}
ListNode dummyHead = new ListNode(0);
dummyHead.next = head;
ListNode lastSorted = head, curr = head.next;
while (curr != null) {
if (lastSorted.val <= curr.val) {
lastSorted = lastSorted.next;
} else {
ListNode prev = dummyHead;
while (prev.next.val <= curr.val) {
prev = prev.next;
}
lastSorted.next = curr.next;
curr.next = prev.next;
prev.next = curr;
}
curr = lastSorted.next;
}
return dummyHead.next;
}
}
复杂度分析
- 时间复杂度: O ( n 2 ) O(n^2) O(n2),其中 n 是链表的长度。
- 空间复杂度:O(1)。
6.5.3 my answer—插入排序
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode() {}
* ListNode(int val) { this.val = val; }
* ListNode(int val, ListNode next) { this.val = val; this.next = next; }
* }
*/
class Solution {
public static ListNode insertionSortList(ListNode head) {
if(head==null)return null;
ListNode dummy = new ListNode(0,head);
ListNode cur = head;
ListNode a = null;
while(cur != null && cur.next != null){ // 判断当前结点cur的下一个结点,需不需要插入到前面某结点间
boolean flag = false; // 用于判断是否
a = dummy;
while (a.next != cur.next){
if(a.next.val> cur.next.val){ // 满足条件,需要插入到a.next位置
ListNode temp1 = a.next;
ListNode temp2 = cur.next.next;
a.next = cur.next;
cur.next.next = temp1;
cur.next = temp2;
flag = true;
break;
}
a = a.next;
}
// 当前结点cur.next未进行插入到前面的操作,才需要cur后移。插入了就不需要后移,因为有cur.next.next补上来
if(!flag){
cur = cur.next;
}
}
return dummy.next;
}
}