鏈表的歸併排序

歸併排序是典型的分治算法思想:


通過不斷遞歸地將鏈表劃分爲兩部分,直到不能劃分爲止,回溯時合併前後兩段分別有序的鏈表,直到得到原始鏈表的有序狀態,整個排序過程時間複雜度爲O(nlogn)

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode* sortList(ListNode* head) {
        if(head==NULL || head->next==NULL) return head;
        ListNode *fast=head,*slow=head;
        //用快指針和慢指針找到鏈表中點 
        while(fast->next && fast->next->next){
            fast=fast->next->next;
            slow=slow->next;
        }
        //把鏈表分成兩部分
        fast=slow->next;
        slow->next=NULL;
        //排序左半部分
        ListNode *l1=sortList(head);
         //排序右半部分
        ListNode *l2=sortList(fast);
        //合併有序鏈表
        return mergeTwoSortedList(l1,l2);
    }
    ListNode * mergeTwoSortedList(ListNode* l1,ListNode*l2){

        ListNode dummy(-1);
        ListNode * p=&dummy;
        while(l1 && l2){

            //從當前兩個有序鏈表頭中選擇一個較小的節點鏈接至有序的鏈表中
            if(l1->val<=l2->val){
                p->next=l1;
                l1=l1->next;
            }else{
                p->next=l2;
                l2=l2->next;
            }
            p=p->next; 
        }
        if(l1) p->next=l1;
        if(l2) p->next=l2;
        return dummy.next;
    }   
};
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章