LeetCode sort-list

问题描述:Sort a linked list in O(n log n) time using constant space complexity.

O(n lgn)时间复杂度,O(1)空间复杂度。

  分析:O(n lgn)时间复杂度的排序算法有几个(快排,归并,希尔,堆),但是O(1)空间复杂度就有一定的压力,只有快排,但是此题是基于链表的,我们还可以多一个选择就是归并排序。

 

  上次是归并排序算法实现时基于数组的我们需要构建一个中间数组,所以空间复杂度O(n),但是由于链表的一些性质我们不需要另外构建一个链表,空间没有消耗,可以为O(1),所以此题都是选择归并排序。PS:好像参考的都是归并,没有找到基于快排的,以后再研究研究。

 

  归并排序原理简单说及时:1,拆分;2,有序数组或者链表的合并。

  有序链表的合并也简单介绍下:我们可以用两个“指针”分别指向两个链表的头部,如果其中一个比另一个小,移动小的那个链表的指针并把小结果放在返回链表中,反之也是这样;一直这样操作下去,直到有一个指针已经超过数组范围。这种方法的时间复杂度为O(m+n),m和n分为为两个链表的长度。(ps:上述博客有完全代买);

  然后就是实现过程:

/**
 * 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* left = head; 
        ListNode* right = head->next;
        ListNode* test = head->next->next; 
        while(test != NULL) {  
            left = right;  
            test = test->next;  
            right = right->next;  
            if(test != NULL) 
                test = test->next;  
        }  
        left->next = NULL;  
        ListNode* head1 = sortList(head);  
        ListNode* head2 = sortList(right); 
        ListNode* merged_head=Merge(head1,head2); 
        return merged_head;
    }
    
    //合并两个有序链表
    ListNode* Merge(ListNode* pHead1, ListNode* pHead2)
    {
        if (pHead1 == NULL)
            return pHead2;
        if (pHead2 == NULL)
            return pHead1;
        ListNode *newListNode = NULL;  //一个遍历存结果,一个用于返回
        ListNode *head = NULL;
        if (pHead1->val <= pHead2->val){         //存头结点先进行一次判断
            newListNode = head = pHead1;
            pHead1 = pHead1->next;
        }
        else{
            newListNode = head = pHead2;
            pHead2 = pHead2->next;
        }
        while (pHead1 != NULL && pHead2!= NULL)          //两个都不为空是一直遍历下去
        {
            if (pHead1->val <= pHead2->val){
                head ->next= pHead1;
                head = head->next;
                pHead1 = pHead1->next;
            }
            else{
                head->next = pHead2;
                head = head->next;
                pHead2 = pHead2->next;
            }
        }
        if (pHead2 == NULL){                             //有一个为空时,直接另外一个直至为空
            head->next = pHead1;
        }
        if (pHead1 == NULL){
            head->next = pHead2;
        }
        return newListNode;
    } 
};

 

posted on 2016-03-29 12:42  延长比赛  阅读(286)  评论(0编辑  收藏  举报

导航