【Sorting】【Linked List】Sort List

Sort List

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

归并排序

思路

  • 使用归并排序,不仅好写,而且似乎对极端情况比较鲁棒一些,顺利过了。
  • 需要注意的是要将链表断开,不断最后会得到一个循环链表,然后收获一枚TLE。

代码

ListNode* sortList(ListNode* head){
    if(head == NULL || head->next == NULL)
        return head;
    ListNode* walker = head;
    ListNode* runner = head;
    while(runner->next!=NULL && runner->next->next!=NULL){
        walker = walker->next;
        runner = runner->next->next;
    }
    ListNode* head1 = head;
    ListNode* head2 = walker->next;
    walker->next = NULL;//非常重要,将链表断开,一分为二
    head1 = sortList(head1);
    head2 = sortList(head2);
    return mergeTwoLists(head1, head2);
}
ListNode *mergeTwoLists(ListNode *l1, ListNode *l2) {
    if(l1 == NULL)
        return l2;
    else if(l2 == NULL)
        return l1;
    ListNode *ResHead, *ResTail;
    ListNode *l1Head = l1;
    ListNode *l2Head = l2; 
    if(l1Head->val < l2Head->val){
        ResHead = l1Head;
        ResTail = l1Head;
        l1Head = l1Head->next;
    }else{
        ResHead = l2Head;
        ResTail = l2Head;
        l2Head = l2Head->next;
    }
    //while(l1Head->next != NULL && l2Head->next != NULL)
    while(l1Head != NULL && l2Head != NULL){
        if(l1Head->val < l2Head->val){
            ResTail->next = l1Head;
            ResTail = l1Head;
            l1Head = l1Head->next;
        }else{
            ResTail->next = l2Head;
            ResTail = l2Head;
            l2Head = l2Head->next;
        }
    }
    if(l1Head != NULL){
        ResTail->next = l1Head;
    }else if(l2Head != NULL){
        ResTail->next = l2Head;
    }
    return ResHead;
}

快速排序

思路

  • 在partition时,我们用最后的节点作为pivot。随机选pivot比较麻烦一点。当我们扫描链表时,如果节点值大于pivot,将节点移到尾部之后;如果节点小于,保持不变。
  • 在qsortList主体,注意pivot左右为空的细节,并且记得把两个链表拼接起来。
  • 做了一些优化,还是TLE在只由1、2、3组成的3w序列上,如果有好心人告诉我如何避免就好了。
  • QuickSort on Singly Linked List
    QuickSort on Doubly Linked List

代码

ListNode* sortList(ListNode* head){
    ListNode* tail = getTail(head);
    return qsortList(head, tail);
}
ListNode* getTail(ListNode* head){
    ListNode* tail = head;
    if(tail == NULL) return tail;//在任何tail->next之前都要三思
    while(tail->next != NULL){
        tail = tail-> next;
    }
    return tail;
}
ListNode* qsortList(ListNode* &head, ListNode* &tail){//以(ListNode* head)的形式调用就是杯具
    if(head == NULL || head->next == NULL)
        return head;
    ListNode* prepivot = NULL;
    ListNode* pivot = NULL;
    partition(head, prepivot, pivot, tail);
    if(head != NULL){
        qsortList(head, prepivot);//在partition中保留prepivot的值,不然会超时
        prepivot->next = pivot;
    }else{
        head = pivot;//如果pivot前面没有元素,head会被置为NULL
    }
    if(pivot->next != NULL){
        qsortList(pivot->next, tail);
    }
    return head;
}
void partition(ListNode* &head, ListNode* &pre, ListNode* &pivot,ListNode* &tail){
    pivot = tail;
    ListNode* dummy = new ListNode(0);
    dummy->next = head;
    pre = dummy;
    ListNode* tar = head;
    while(tar != pivot){
        if(tar->val > pivot->val){
            pre->next = tar->next;//重要
            tar->next = NULL;
            tail->next = tar;
            tail = tar;
            tar = pre->next;
        }else{
            pre = tar;
            tar = tar->next;
        }
    }
    pre->next = NULL;//重要
    head = dummy->next;
}

posted on 2014-07-20 00:30  小唯THU  阅读(396)  评论(0)    收藏  举报

导航