147挿入ソートリスト**
https://leetcode.com/problems/insertion-sort-list/
タイトル説明
挿入ソートを使用してリンクリストを並べ替えます。
挿入ソートのアルゴリズム:
- 挿入ソートの反復処理し、各反復1つの入力要素を消費し、ソートされた出力リストを成長させること。
- 各反復において、挿入ソートが、入力データから一つの要素を取り除き、それがソートされたリスト内に属する場所を見つけ、そしてインサートを。
- 何の入力要素が残っていないまで、それは繰り返されます。
例1:
Input: 4->2->1->3
Output: 1->2->3->4
例2:
Input: -1->5->3->4->0
Output: -1->0->3->4->5
C ++の実装1
すでにソートされたノードの順序保存仮想ノード、ダミーの使用は下降し、最終的に結果を逆にしています。
p
ダミー初期化し、現在関心のある各ノードと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);
}
};