147. Insertion Sort List**
https://leetcode.com/problems/insertion-sort-list/
题目描述
Sort a linked list using insertion sort.
Algorithm of Insertion Sort:
- Insertion sort iterates, consuming one input element each repetition, and growing a sorted output list.
- At each iteration, insertion sort removes one element from the input data, finds the location it belongs within the sorted list, and inserts it there.
- It repeats until no input elements remain.
Example 1:
Input: 4->2->1->3
Output: 1->2->3->4
Example 2:
Input: -1->5->3->4->0
Output: -1->0->3->4->5
C++ 实现 1
使用 dummy 虚拟节点, 保存已经排好序的节点, 顺序是从大到小, 最后 reverse 得到结果.
p
初始化为 dummy, 然后每次用当前关注的节点 ptr
和 p
所指向的下一个节点进行比较, 如果遇到合适的位置, 就可以将 ptr
插入到 p
和 p->next
之间.
class Solution {
private:
ListNode* reverse(ListNode *head) {
ListNode *prev = nullptr;
while (head) {
auto tmp = head->next;
head->next = prev;
prev = head;
head = tmp;
}
return prev;
}
public:
ListNode* insertionSortList(ListNode* head) {
if (!head || !head->next) return head;
ListNode *dummy = new ListNode(0);
dummy->next = head;
auto ptr = head->next;
head->next = nullptr; // head 加入到 dummy 链表后, 要注意和 next 节点断开
auto p = dummy;
while (ptr) { // ptr 指向当前要访问的元素, 它要和 dummy 链表已存在的节点进行对比
auto tmp = ptr->next;
while (p->next && p->next->val > ptr->val) // 将较小的元素排在 dummy 链表的后面, 最后进行 reverse
p = p->next;
ptr->next = p->next;
p->next = ptr;
ptr = tmp; // ptr 接着指向下一个节点
p = dummy; // p 恢复原位, dummy 链表的起始位置
}
return reverse(dummy->next);
}
};