1. 程式人生 > 實用技巧 >sort-list 歸併排序連結串列

sort-list 歸併排序連結串列

題目:

在O(n log n)的時間內使用常數級空間複雜度對連結串列進行排序。 Sort a linked list inO(nlogn) time using constant space complexity.

示例;

輸入:{3,2,4}    輸出:{2,3,4}

程式碼:

 1 /**
 2  * struct ListNode {
 3  *    int val;
 4  *    struct ListNode *next;
 5  * };
 6  */
 7 
 8 class Solution {
 9 public:
10     /**
11      * 
12      * @param head ListNode類 
13 * @return ListNode類 14 */ 15 ListNode* FindMiddleNode(ListNode* head) { 16 ListNode* fast = head; //利用快慢指標找到當前中間節點 17 ListNode* slow = head; 18 while(fast->next != NULL && fast->next->next != NULL){ 19 fast = fast->next->next;
20 slow = slow->next; 21 } 22 return slow; 23 } 24 ListNode* MergeList(ListNode* l1, ListNode* l2) { 25 if(l1 == NULL) 26 return l2; 27 if(l2 == NULL) 28 return l1; 29 ListNode* result; //結果 30 ListNode* newhead; //
頭節點 31 auto first = l1->next; //表示歸併排序中的兩個分割槽 32 auto second = l2->next; 33 if(l1->val > l2->val){ //l1較小則為頭節點,反之則頭節點為l2 34 result = newhead = l2; 35 first = l1; 36 } 37 else{ 38 result = newhead = l1; 39 second = l2; 40 } 41 while(first != NULL || second != NULL){ 42 if(second == NULL){ //當第二塊為空 43 result->next = first; break; 44 } 45 else if(first == NULL){ //當第一塊為空 46 result->next = second; break; 47 } 48 // 歸併排序,較小的先插入result的尾部,由於這裡在sort函式中有將右末尾結點設為NULL所以會停止迴圈 49 if(first->val > second->val){ 50 result->next = second; 51 second = second->next; 52 result = result->next; 53 } 54 else{ 55 result->next = first; 56 first = first->next; 57 result = result->next; 58 } 59 } 60 return newhead; 61 } 62 ListNode* sortList(ListNode* head) { 63 if(head == NULL || head->next == NULL) 64 return head; 65 ListNode* mid = FindMiddleNode(head); 66 ListNode* midnext = mid->next; 67 mid->next = NULL; //將連結串列劃分 68 return MergeList(sortList(head), sortList(midnext)); 69 } 70 };

我的筆記:

由於本函式的要求時間複雜度為O(nlogn),故使用歸併排序法。

leetcode官網詳解:https://leetcode-cn.com/problems/sort-list/solution/148-pai-xu-lian-biao-bottom-to-up-o1-kong-jian-by-