LeetCode | Sort List

来源:互联网 发布:tensorflow与spark 编辑:程序博客网 时间:2024/06/06 07:12

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

题目解析:

之前见过的都是针对数组进行排序的,现在针对链表,其能用的只有:冒泡排序,快速排序,归并排序。归并排序用于链表的时候就不需要额外设置辅助空间了,直接用指针变换就能解决。

方案一:快速排序

经过验证,超时了,在链表基本有序的时候,会得到很坏的情况。

但一定要注意其中的情况:

快速排序,要选一个结点当主元,在链表里,就是将这个点摘除,然后剩下的分成大节点链表和小节点链表,然后两个链表递归进行。最后将两个链表和这个主元结点进行合并!

class Solution {public:    ListNode *sortList(ListNode *head) {        if(head == NULL || head->next == NULL)            return head;        int key = head->val;        ListNode *small=NULL,*big=NULL; //小节点和大节点指针        ListNode *psmall,*pbig;         //指向最后的指针        ListNode *priv = head;          //快排的当前指针,必须要取出来,最后和small,big合并        ListNode *p = head->next;        priv->next = NULL;              //将其赋值为空,和上面的那一句不能交换,否则出错!!        while(p){            if(p->val > key){                if(big == NULL){    //处理big指针为空的情况                    big = p;                    pbig = big;                }else{                    pbig->next = p;                    pbig = p;                }            }else{                if(small == NULL){                    small = p;                    psmall = p;                }else{                    psmall->next = p;                    psmall = p;                }            }            p = p->next;        }        if(small)   //将小节点指针的末尾赋值为空            psmall->next = NULL;        if(big)            pbig->next = NULL;        small = sortList(small);        big = sortList(big);        //如果小节点指针为空,处理这种特殊情况        if(small == NULL){            priv->next = big;            return priv;        }        //将两个链表和一个结点合并!        p = small;        while(p->next)            p = p->next;        p->next = priv;        priv->next = big;        return small;    }};


方案二:归并排序

这个时间复杂度比较好,能满足题目的要求。但是我们在用快慢指针的时候,要注意,这里要讲链表分成两个链表,最后要将pre的前一个结点的next赋值为NULL!不然会陷入死循环。这个错误也是找了半天才找的的。还是比较讨厌链表的题目,虽然不难,但各种错误……

class Solution {public:    ListNode *sortList(ListNode *head) {        if(head == NULL || head->next == NULL)            return head;        ListNode *pre,*post,*ppre;        ppre = pre = post = head;        while(post && post->next){            ppre = pre;            pre = pre->next;            post = post->next->next;        }        ppre->next = NULL;  //必须将链表截断!        ListNode *p,*q;        p = sortList(head);        q = sortList(pre);        head = Merge(p,q);        return head;    }    ListNode *Merge(ListNode *p,ListNode*q){        if(!p)            return q;        if(!q)            return p;        ListNode *head = NULL;        ListNode *pre = head;        while(p && q){            if(p->val < q->val){                if(head == NULL)                    head = p;                else                    pre->next = p;                pre = p;                p = p->next;            }            else{                if(head == NULL)                    head = q;                else                    pre->next = q;                pre = q;                q = q->next;            }        }        if(q)            pre->next = q;        if(p)            pre->next = p;        return head;    }};





0 0