链表排序(sort-list)

链表排序

1、要求:

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

2、思路

因为题目要求复杂度为O(nlogn),故可以考虑归并排序的思想。
归并排序的一般步骤为:
1)将待排序数组(链表)取中点并一分为二;
2)递归地对左半部分进行归并排序;
3)递归地对右半部分进行归并排序;
4)将两个半部分进行合并(merge),得到结果。

3、代码:

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
/*
  考点:
  1. 快慢指针;2. 归并排序。
  复杂度分析:
             T(n)            拆分 n/2, 归并 n/2 ,一共是n/2 + n/2 = n
            /    \           以下依此类推:
          T(n/2) T(n/2)      一共是 n/2*2 = n
         /    \  /     \
        T(n/4) ...........   一共是 n/4*4 = n
 
       一共有logn层,故复杂度是 O(nlogn)
 */

class Solution {
public:
    ListNode *sortList(ListNode *head) {
        if (!head || !head->next) return head;
          
        ListNode* p = head, *q = head->next;  //使用快慢指针寻找中点
        while(q && q->next) {
            p = p->next;
            q = q->next->next;
        }
          
        ListNode* left = sortList(p->next);   //先后半部分
        p->next = NULL;
        ListNode* right = sortList(head);
          
        return merge(left, right);
    }
     
    ListNode *merge(ListNode *left, ListNode *right) {
        ListNode dummy(0);
        ListNode *p = &dummy;
        while(left && right) {
            if(left->val < right->val) {
                p->next = left;
                left = left->next;
            }
            else {
                p->next = right;
                right = right->next;
            }
            p = p->next;
        }
        if (left) p->next = left;
        if (right) p->next = right;
        return dummy.next;
    }
};


猜你喜欢

转载自blog.csdn.net/ye1215172385/article/details/80138550
今日推荐