對單鏈表進行插入排序,返回排序後頭節點。要求原地排序。
維護一個已排序部分鏈表(虛擬頭節點 dummy),遍歷原鏈表,將每個節點摘下,在已排序部分找到插入位置並插入。
dummy,dummy->next = headsortedTail 指向已排序部分尾部(初始為 head)cur = sortedTail->next(待插入節點)cur->val >= sortedTail->val,直接擴展已排序部分dummy 開始找第一個大於 cur->val 的節點 pre,插入到 pre 後cur 與原後繼的連接,避免環class Solution {
public:
ListNode* insertionSortList(ListNode* head) {
if (!head || !head->next) return head;
ListNode dummy(0);
dummy.next = head;
ListNode *sortedTail = head;
ListNode *cur = head->next;
sortedTail->next = nullptr; // 斷開,已排序部分只有 head
while (cur) {
ListNode *next = cur->next;
cur->next = nullptr;
if (cur->val >= sortedTail->val) {
sortedTail->next = cur;
sortedTail = cur;
} else {
ListNode *pre = &dummy;
while (pre->next && pre->next->val < cur->val) pre = pre->next;
cur->next = pre->next;
pre->next = cur;
}
cur = next;
}
return dummy.next;
}
};
next 並置 cur->next=nullptrdummy 開始,而非 head,否則無法處理插到頭部的情況sortedTail 僅在尾插時更新,中間插入不動鏈表插入排序雖非最優(歸併排序 O(n log n)),但思路直觀,是理解鏈表指針操作的優秀練習。