1. 插入排序的基本思想:將一個節點插入到一個有序的序列中。對於鏈表而言,要依次從待排序的鏈表中取出一個節點插入到已經排好序的鏈表中,也就是說,在單鏈表插入排序的過程中,原鏈表會截斷成兩部分,一部分是原鏈表中已經排好序的節點,另一部分是原鏈表中未排序的節點,這樣就需要在排序的過程中設置一個當前節點,指向原鏈表未排序部分的第一個節點。
注意單鏈表插入排序和數組插入排序的不同:數組插入排序是從排好序的部分的最后一個節點往前找,找到第一個比它小的數,然后插到其后面;而單鏈表只能從前往后遍歷,找到第一個比當前節點大的值結束,因此在遍歷已經排好序的鏈表部分的時候,需要兩個指針,一個指針用於往前遍歷(該指針假設為遍歷指針),一個指針用於記錄遍歷指針指向的當前節點的前一個節點(該指針假設為遍歷指針),這樣當遍歷指針找到第一個比待插入節點的值大的節點的時候,就可以將待插入節點插入到記錄指針的后面。(之所以使用兩個指針,是因為單鏈表不能反指)
插入排序分兩種情況,一種是當前節點的值比已經排好序的尾節點的值大,則直接將當前節點掛在已排序的節點即可;一種是當前節點值比已經排好序的尾節點的值小,則需將已排好序的鏈表部分從頭到尾遍歷,找到第一個比當前節點值大的節點,插入到其前面即可。因為可能待插入的節點可能在第一個節點的前面,因此另外創建一個頭結點,指向已經排好序的鏈表的第一個節點。這樣可以每次插入新的節點的時候,將上面所提到的記錄節點初始化為新創建的頭結點,這樣便於在第一個節點前面插入新節點。
1 class Solution 2 3 { 4 5 public: 6 7 ListNode *insertionSortList(ListNode *head) 8 9 { 10 11 if(head==NULL || head->next==NULL) return head; 12 13 ListNode *cur=head; 14 15 ListNode *helper=new ListNode(0); 16 17 ListNode *pre; 18 19 while(cur) 20 21 { 22 23 ListNode *next=cur->next; 24 25 pre=helper; 26 27 while(pre->next!=NULL && pre->next->val<cur->val) 28 29 { 30 31 pre=pre->next; 32 33 } 34 35 cur->next=pre->next; 36 37 pre->next=cur; 38 39 cur=next; 40 41 } 42 43 return helper->next; 44 45 } 46 47 48 49 }