leetcode-链表中的递归归并排序

链表中的递归归并排序 Sort List

三点:

归并排序的整体思想
找到一个链表的中间节点的方法
合并两个已排好序的链表为一个新的有序链表

要求是时间复杂度是nlogn ,空间是常数级别。
在对数组进行排序时,归并排序时间复杂度为nlongn,空间复杂度为n;快速排序的时间复杂度是n~nlogn之间,空间复杂度是logn;堆排序的时间复杂度是nlogn,空间复杂度是1.但是在对链表进行排序时,归并排序可以实现常数的空间复杂度,而且时间复杂度依然是nlogn。

归并排序法:因为原来使用归并时,空间复杂度都是 O(N)的,需要复制出相等的空间来进行赋值归并。对于链表,实际上是可以实现常数空间占用的(链表的归并 排序不需要额外的空间)。利用归并的思想,递归地将当前链表分为两段,然后对两段分别进行递归调用排序方法,然后合并(merge),分两段的方法是使用 fast-slow 法,用两个指针,一个每次走两步,一个走一步,直到快的走到了末尾,然后慢的所在位置就是中间位置,这样就分成了两段。

#include <stdlib.h>
#include<iostream>
using namespace std;
struct ListNode
{
    int val;
    ListNode *next;
    ListNode(int x): val(x), next(NULL) {}
};
ListNode *findMiddle(ListNode *head)
{
    ListNode *middle = head;
    ListNode *runner = head->next;
    while(runner != NULL && runner->next != NULL)
    {
        middle = middle->next;
        runner = runner->next->next;
    }
    return middle;
}
ListNode *mergeTwoLists(ListNode *l1, ListNode *l2)
{
    if (l1 == NULL)
        return l2;
    if (l2 == NULL)
        return l1;
    ListNode *pre = new ListNode(0);
    ListNode *head = pre;
    while (l1 != NULL && l2 !=NULL)
    {
        if(l1->val > l2->val)
        {
            head->next = l2;
            l2 = l2->next;            
        }
        else
        {
            head->next = l1;
            l1 = l1->next; 
        }
        head = head->next;
    }
    if (l1 == NULL)
    {
        head->next = l2;
    }
    if (l2 == NULL)
    {
        head->next = l1;
    }
    return pre->next;
}
ListNode *sortList(ListNode *head) 
{
    if (head == NULL || head->next == NULL)
    {
        return head;
    }
    ListNode *middle = findMiddle(head);
    ListNode *right = sortList(middle->next);
    middle->next = NULL;
    ListNode *left = sortList(head);
    return mergeTwoLists(left, right);
}
int main()
{
    ListNode n1(3), n2(4), n3(2), n4(1), n5(5);
    n1.next = &n2;
    n2.next = &n3;
    n3.next = &n4;
    n4.next = &n5;
    ListNode *head = NULL;
    head = sortList(&n1);
    ListNode *head1;

    while (head != NULL)
    {
        cout << head ->val << endl;
        head = head ->next;
    }
    return 0;
}





参考链接:https://www.cnblogs.com/qiaozhoulin/p/4585401.html
参考链接:https://blog.csdn.net/weixin_39688949/article/details/78472246?utm_medium=distribute.pc_relevant_t0.none-task-blog-BlogCommendFromBaidu-1&depth_1-utm_source=distribute.pc_relevant_t0.none-task-blog-BlogCommendFromBaidu-1

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值