# 对链表进行插入排序(147)
# 题目
对链表进行插入排序。
# 插入排序算法
- 插入排序是迭代的,每次只移动一个元素,直到所有元素可以形成一个有序的输出列表。
- 每次迭代中,插入排序只从输入数据中移除一个待排序的元素,找到它在序列中适当的位置,并将其插入。
- 重复直到所有输入数据插入完为止。
# 算法
因为单链表不能向前查找,所以我们每次寻找插入点的时候都从前向后寻找插入点
- 如果是空链表或只有一个节点的链表,直接返回链表
- 先设置哨兵节点
sentinel
- 从
head.next
开始依次向后循环,每一轮循环为了寻找current
(即每一轮的head.next
)的插入点,循环结束条件是head
和head.next
均存在 - 如果
current.val
大于head.val
,则当前current
位置正确无需移动,直接让head
移动到下一位, - 否则我们设置指针
index
指向sentinel.next
,并且向后移动查找current
的插入点,当index.next.val
大于等于current.val
时,index
和index.next
之间就是插入点,我们将current
节点拼接在index
和index.next
之前。此时head
(即current
没有移动之前的前驱节点)后面的节点已经是原来head.next.next
节点了,所以我们不需要移动head
指针,继续判断即可
/**
* Definition for singly-linked list.
* function ListNode(val) {
* this.val = val;
* this.next = null;
* }
*/
export const insertionSortList = (head) => {
if (!head || !head.next) return head;
let sentinel = new ListNode();
sentinel.next = head;
while (head && head.next) {
let current = head.next;
if (current.val >= head.val) {
head = head.next;
} else {
let index = sentinel;
while (index.next.val < current.val) {
index = index.next;
}
head.next = head.next ? head.next.next : null;
current.next = index.next;
index.next = current;
}
}
return sentinel.next;
};
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
26
27
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27