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

时间复杂度要求O(nlogn),可用快排,归并排,堆排来实现。

1,快排。快排基于分治法,取中枢值pivot作划分partition,一趟partition()操作后,中枢值位置定,表中元素被中枢值一分为二,递归划分两子表。当然划分函数partition()很重要。

代码实现:

/**
 * 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) {
        
        return quickSort(head,NULL);
    }
    ListNode* quickSort(ListNode *head,ListNode *end){
        if (head!=end){
            ListNode* pivot = partion(head, end);//返回中枢值的指针
            quickSort(head,pivot);
            quickSort(pivot->next,end);
        }
        return head;
    }
    ListNode* partion(ListNode *head,ListNode *end){
        int key = head->val;
        ListNode *p = head;
        ListNode *q = head->next;
        while(q!=end){
            if(q->val<key){
                p = p->next;
                swap(p,q);
            }
            q = q->next;
        }
        swap(head,p);
        return p;
    }
    void swap(ListNode *p,ListNode *q){
        int temp = p->val;
        p->val = q->val;
        q->val = temp;
    }
};

2,归并排。

归并排序的一般步骤为:
1)将待排序数组(链表)取中点并一分为二;
2)递归地对左半部分进行归并排序;
3)递归地对右半部分进行归并排序;
4)将两个半部分进行合并(merge),得到结果。


代码实现:
/**
 * 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 || !head->next){
            return head;
        }
        ListNode *p = head;
        ListNode *q = head->next;
        while(q && q->next){//快慢指针思路,快指针一次走两步,慢指针一次走一步,快指针在链表末尾时,慢指针恰好在链表中点
            p = p->next;
            q = q->next->next;
        }
        ListNode *r = sortList(p->next);
        p->next = NULL;
        ListNode *l = sortList(head);
        return merge(l,r);
    }
    ListNode *merge(ListNode *left,ListNode *right){ //写出merge函数,即如何合并链表。
        ListNode dummy(0); //创建结构体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;//结构体取属性
    }
};

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值