關於鏈表的歸併排序

sort list

算法概論第一週


題目鏈接

題目描述

Sort a linked list in O(n log n) time using constant space complexity.
Example 1:

Input: 4->2->1->3
Output: 1->2->3->4

Example 2:

Input: -1->5->3->4->0
Output: -1->0->3->4->5

##題目分析

  • O(nlogn)O(n log n)的複雜度,肯定要求要在原鏈表數據結構的基礎上進行排序,將其轉換爲數組是開銷很大的。
  • 避免內存分配

##解題思路

  • 標準的歸併排序,原理如圖:
    圖片加載失敗
  • 同時要考慮鏈表的數據結構
  • 故每次遞歸的過程分爲找鏈表中點和排序
  • 注意排序鏈表長度爲0和1的特殊情況
  • 注意兩條鏈表同時排序後,剩下一小段鏈表的處理

##代碼

class Solution {
public:
    ListNode* sortList(ListNode* head) {
        ListNode* fid = head;
        int nodeNum = 0;
        while(fid){
        	nodeNum++;
        	fid = fid->next;
        }
        if(nodeNum == 0 || nodeNum == 1)
            return head;
        else{
            int halfNum = nodeNum / 2;
            ListNode* fhalf = head;
            for(int i = 0; i < halfNum - 1; i++){
                fhalf = fhalf->next;
            }
            ListNode* rhalf = fhalf->next;
            fhalf->next = NULL;
            return merge(sortList(head), sortList(rhalf));
        }
    }
    ListNode* merge(ListNode* l1, ListNode* l2){
        ListNode* resHead = new ListNode(-1);
        ListNode* resCurr = resHead;
        while(l1 && l2){
            if(l1->val < l2->val){
                resCurr->next = l1;
                l1 = l1->next;
            }
            else{
                resCurr->next = l2;
                l2 = l2->next;
            }
            resCurr = resCurr->next;
        }
        if(l1){
            resCurr->next = l1;
        }
        else if(l2){
            resCurr->next = l2;
        }
        return resHead->next;
    }
};
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章