Leetcode 147 對連結串列進行插入排序
阿新 • • 發佈:2018-11-13
按照陣列插入排序的思路,需要把陣列分成以排序和未排序的兩部分:
每次從未排序的陣列中拿出一個插入已排序的陣列中,指到未排序陣列未空。在插入的過程中涉及到陣列的遍歷查詢,而陣列是可以按下標從後向前遍歷的:
void InsertSort(int a[], int n) { for(int i=1;i<n;i++) { int value=a[i]; int index=i-1; while(index>=0&&a[index]>value) { a[index+1]=a[index]; index--; } a[index+1]=value; } }
但單鏈表只能單向順序遍歷,因此必須用兩個指標來分別遍歷有序連結串列和未排序連結串列,因此必須先構建一個新連結串列作為有序連結串列最終返回:
/** * 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==NULL || head->next == NULL) return head; //創造一個新的連結串列頭部 ListNode* pre = new ListNode(-1); //用一個臨時變數儲存頭節點 ListNode* ans = pre; //cur是原連結串列上的指標 ListNode* cur = head; while (cur != NULL) { //每次迴圈前重置pre為頭結點,這樣保證每次都從頭往後遍歷 pre = ans; //當pre.next.val大於cur.val時停止迴圈 while (pre->next != NULL && pre->next->val < cur->val) { pre = pre->next; } //pre->next->val 大於 cur->val,此時應該把cur插入到pre後 //儲存原連結串列當前節點的下一節點 ListNode* tmp = cur->next; //把cur插入到pre之後 cur->next = pre->next; pre->next = cur; //cur指標後移一位 cur = tmp; } return ans->next; } };
發現上面的head賦值給cur 之後就再也沒用用過,所以乾脆直接用head來遍歷未排序陣列:
class Solution { public: ListNode* insertionSortList(ListNode* head) { if(head==NULL || head->next == NULL) return head; ListNode* ans = new ListNode(-1); while (head != NULL) { ListNode* tmp= head->next; ListNode* cur= ans; while (cur->next != NULL && cur->next->val < head->val) { cur = cur->next; } head->next = cur->next; cur->next = head; head = tmp; } return ans->next; } };