链表的排序

148. 排序链表

你链表的头结点 head ,请将其按 升序 排列并返回 排序后的链表 。

进阶:

你可以在 O(n log n) 时间复杂度和常数级空间复杂度下,对链表进行排序吗?

示例 1:

image-20210911105926649

输入:head = [4,2,1,3]
输出:[1,2,3,4]

示例 2:

image-20210911105945165

输入:head = [-1,5,3,4,0]
输出:[-1,0,3,4,5]

示例 3:

输入:head = []
输出:[]

链表排序的最佳方法:归并排序

1.找到中间节点

2.将中间节点断成左右两半,然后再次递归找到中间节点,再次进行分割,直到最后分割成一个一个的单个元素

3.然后两两排序,之后四四排序…直到最后将整张链表排成一个有序链表

这个思想和归并排序一样,归并排序的原理也是将数据分割成小部分,然后每一个小部分进行排序,让局部有序,然后整体有序

class Solution {
public:
//链表的排序:归并排序
//1.找到中间节点
//2.将链表分为两部分
//3.实现有序链表的排序
    ListNode*Sort(ListNode*&l,ListNode*&r)
    {
    //到这里就是排序的思想了,排序思想和合并两个有序链表的思想差不多
    //创建新的节点,然后按照插入排序的思想,谁大谁就插入
    //如果这边有点问题的话可以去看看合并两个有序链表
        ListNode*dummyHead=new ListNode(0);
        ListNode*cur=dummyHead;
        while(l!=nullptr&&r!=nullptr)
        {
            if(l->val<=r->val)
            {
                cur->next=l;
                cur=cur->next;
                l=l->next;
            }
            else
            {
                cur->next=r;
                cur=cur->next;
                r=r->next;
            }
        }
        if(l!=nullptr)
        {
            cur->next=l;
        }
        if(r!=nullptr)
        {
            cur->next=r;
        }
        return dummyHead->next;
    }
    //传递参数时记得引用传递
    ListNode*MergSort(ListNode*&head)
    {
    //判断头节点的下一个节点是否为空,如果是,直接返回头节点
        if(head->next==nullptr)
        return head;
        //定义快慢指针,寻找中间节点
        ListNode*slow=head;
        ListNode*fast=head;
        ListNode*prev=nullptr;
        while(fast&&fast->next)
        {
            prev=slow;
            slow=slow->next;
            fast=fast->next->next;
        }
        //此时slow所在的位置就是中间节点所在的位置,prev指向slow的前一个节点
        //我们人为的让链表从slow这个地方断开,head->prev是链表的前半段,slow到完是链表的右半部分
        prev->next=nullptr;
		//递归在左、右两端继续找中间节点
        ListNode*l=MergSort(head);
        ListNode*r=MergSort(slow);
        //当分割的不能分割时,进行排序,最开始两两排序,到后来四四排序
        return Sort(l,r);
    }
    ListNode* sortList(ListNode* head) {
    //1.判断节点是否为空
        if(head==nullptr)
        return head;
        //2.进入归并排序,寻找中间节点
        return MergSort(head);

    }
};
  • 33
    点赞
  • 71
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 25
    评论
在Python中,可以使用多种排序算法链表进行排序。常见的适合链表排序算法包括冒泡排序、选择排序、插入排序、归并排序、快速排序、计数排序、桶排序和基数排序。这些算法都可以应用于链表排序,并根据具体情况选择最合适的算法。不过,希尔排序链表排序中并不适合使用,而堆排序虽然可以用于链表排序,但不被建议使用。 具体实现链表排序的方法可以根据不同的排序算法进行选择。下面以归并排序为例,介绍一种Python实现链表排序的方法: 1. 定义一个函数mergeSort,该函数用于实现归并排序。 2. 在mergeSort函数中,先判断链表是否为空或只有一个节点,如果是,则返回链表。 3. 如果链表节点个数大于等于2,则将链表拆分成两个子链表,可以通过快慢指针的方法找到链表的中间节点,并将链表分成两部分。 4. 对两个子链表分别递归调用mergeSort函数,将它们分别排序。 5. 定义一个merge函数,用于合并两个已排序链表。 6. 在merge函数中,创建一个新的链表作为结果链表的头节点。 7. 依次比较两个链表的节点值,并将较小值的节点添加到结果链表中,直到其中一个链表为空。 8. 将另一个链表剩余的节点添加到结果链表的末尾。 9. 返回结果链表作为mergeSort函数的结果。 通过以上步骤,就可以实现对链表进行归并排序的功能。
评论 25
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

 落禅

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值