98 链表排序-------快速排序

二、快速排序
使用快排也可以解决。但是注意,要加一个优化才可以过大数据,就是判断一下是不是整个链条是相同的节点,比如2 2 2 2 2 2 2 ,这样的就直接扫一次不用执行  快排,否则它会是N平方的复杂度。
  快速排序1   
   快速排序的主要思想是: 
   1)选定一个基准元素 
   2)经过一趟排序,将所有元素分成两部分 
   3)分别对两部分重复上述操作,直到所有元素都已排序成功 
   因为单链表只能从链表头节点向后遍历,没有prev指针,因此必须选择头节点作为基准元素。这样第二步操作的时间复杂度就为O(n)。由于之后都是分别对两部分完成上述操作,因此会将链表划分为lgn个段,因此时间复杂度为O(nlgn) 
示意图如下
 
代码如下(记住这个算法)
class Solution {
public:
    /*
     * @param head: The head of linked list.
     * @return: You should return the head of the sorted linked list, using constant space complexity.
     */
    ListNode * sortList(ListNode * head) {
        // write your code here
         if(head==NULL||head->next==NULL)    return head;
        quick_sort(head,NULL);
        return head;
    }
    void quick_sort(ListNode *pBegin,ListNode *pEnd){
        if(pBegin==pEnd)    return;//return 到被调用的地方quick_sort(head,NULL);

        ListNode *mid=partion(pBegin,pEnd);
        quick_sort(pBegin,mid);
        quick_sort(mid->next,pEnd);
    }
    ListNode *partion(ListNode *pBegin,ListNode *pEnd){
        if(pBegin==pEnd||pBegin->next==pEnd)    return pBegin;
        int key=pBegin->val;    //选择pBegin作为基准元素
        ListNode *p=pBegin,*q=pBegin;
        while(q!=pEnd){   //从pBegin开始向后进行一次遍历
            if(q->val<key){
                p=p->next;
                swap(&p->val,&q->val);
            }
            q=q->next;
        }
        swap(&p->val,&pBegin->val);
        return p;
    }
    void swap(int *a,int *b){
        int t=*a;
        *a=*b;
        *b=t;
    }
};


猜你喜欢

转载自blog.csdn.net/weixin_41413441/article/details/79084868
98