链表插入排序

147. 对链表进行插入排序

给定单个链表的头 head ,使用 插入排序 对链表进行排序,并返回 排序后链表的头

插入排序 算法的步骤:

  1. 插入排序是迭代的,每次只移动一个元素,直到所有元素可以形成一个有序的输出列表。
  2. 每次迭代中,插入排序只从输入数据中移除一个待排序的元素,找到它在序列中适当的位置,并将其插入。
  3. 重复直到所有输入数据插入完为止。

下面是插入排序算法的一个图形示例。部分排序的列表(黑色)最初只包含列表中的第一个元素。每次迭代时,从输入数据中删除一个元素(红色),并就地插入已排序的列表中。

对链表进行插入排序。

示例 1:

img

1
2
输入: head = [4,2,1,3]
输出: [1,2,3,4]

示例 2:

img

1
2
输入: head = [-1,5,3,4,0]
输出: [-1,0,3,4,5]
插入排序
image-20221112180746345 image-20221112180804285

用一个r指针记录已排好序的链表尾部

用cur遍历待排序的元素

  • 如果当前元素小于r所指向的元素,从头开始遍历要插入的位置
  • 如果当前元素大于等于r所指向的元素,不需要插入,r直接右移
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
class Solution {
public ListNode insertionSortList(ListNode head) {
if(head == null) return head;
ListNode dummy = new ListNode(0);
dummy.next = head;
ListNode cur = head.next; //用于遍历链表
ListNode r = head; //(dummy,r]为已排好序链表
while(cur != null){
if(r.val <= cur.val){//链尾元素比待插入元素还小,直接改变链尾元素
r = r.next;
}else{
ListNode pre = dummy; //用于找到cur要插入的位置
while(pre.next.val < cur.val ){
pre = pre.next;
}
//pre.next.val >= cur.val, cur插入到pre后面
r.next = cur.next;
cur.next = pre.next; //插入
pre.next = cur;
}
cur = r.next;
}
return dummy.next;
}
}

时间复杂度:$O(n)$


链表插入排序
http://example.com/2023/05/29/算法/链表/8. 链表插入排序/
作者
PALE13
发布于
2023年5月29日
许可协议