題目:跳轉至 147. 對連結清單進行插入排序
對連結清單進行插入排序。
![](https://img.laitimes.com/img/_0nNw4CM6IyYiwiM6ICdiwiIyVGduV2YfNWawNiZpdmLxgDN2ATOwMjMxITMxAjMwIzLc52YucWbp5GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.gif)
插入排序的動畫示範如上。從第一個元素開始,該連結清單可以被認為已經部分排序(用黑色表示)。
每次疊代時,從輸入資料中移除一個元素(用紅色表示),并原地将其插入到已排好序的連結清單中。
插入排序算法:
- 插入排序是疊代的,每次隻移動一個元素,直到所有元素可以形成一個有序的輸出清單。
- 每次疊代中,插入排序隻從輸入資料中移除一個待排序的元素,找到它在序列中适當的位置,并将其插入。
- 重複直到所有輸入資料插入完為止。
示例 1:
輸入: 4->2->1->3
輸出: 1->2->3->4
示例 2:
輸入: -1->5->3->4->0
輸出: -1->0->3->4->5
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode* insertionSortList(ListNode* head) {
}
};
思路:
看動畫很清晰,從前往後周遊,如果是遞增就下一個,否則把目前節點值在前段已排序過的序列裡挨個比較,直到找出合适位置,插入,繼續周遊比較下一個節點的值。
還是參考了題解的,中間要注意連結清單的前後指向,以及頭節點的比較,在頭節點前再加入一個虛拟節點便于在頭節點之前的插入。
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode* insertionSortList(ListNode* head) {
if(head==nullptr)
return head;
ListNode* lastSorted=head; //隻一位數必定有序
ListNode* cur=head->next; //目前值和第一位比較是以指向已排序連結清單的next
ListNode* dummyNode=new ListNode(0); //虛拟節點
dummyNode->next=head;
while(cur!=nullptr){
if(cur->val>=lastSorted->val) //目前指向比最後有序值大
lastSorted=lastSorted->next;
else{
ListNode* prev=dummyNode; //從最開始的虛拟節點頭的下一個(head)開始周遊
while(prev->next->val<=cur->val) //直到prev->next指向第一個大于cur的值
prev=prev->next;
lastSorted->next=cur->next; //最後一個排序數此時為cur,下一個是未排序的第一個就是cur->next
cur->next=prev->next; //上面一句排序的最後一個節點的next要指向之前已排序的序列中大于cur值的部分l序列,即prev->next
prev->next=cur; //prev->next原先指向第一個大于cur的值,現在指向cur
//上三句,舉例如[1,4,2], cur指向2,lastSorted指向4, prev指向1
//4->next指向nullptr, 2->next應該指向4,即指向1->next, 最後1->next指向2
}
cur=lastSorted->next; //目前值即已排序後的第一個節點
}
return dummyNode->next;
}
};
連結清單真的要舉例子畫圖了解!!!!好繞啊