单链表的排序-双指针

单链表的排序-牛客

思路

1、归并排序+双指针
归并排序:递归,涉及划分左右区间;合并区间,涉及左右指针,类似合并两个排序的链表

  • 递归
    1、终止条件: 当子链表划分到为空或者只剩一个节点时,不再继续划分,往上合并。
    2、递归函数入参和返回值: 入参:链表头结点,返回值:每次返回两个排好序且合并好的子链表。
    3、本层逻辑: 找到这个链表的中间节点,从前面断开,分为左右两个子链表,进入子问题排序。
  • 如何找中间结点?
    准备三个指针,快指针right每次走两步,慢指针mid每次走一步,前序指针left每次跟在mid前一个位置。三个指针遍历链表,当快指针到达链表尾部的时候,慢指针mid刚好走了链表的一半,正好是中间位置。
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None
#
# 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
#
# 
# @param head ListNode类 the head node
# @return ListNode类
#
class Solution:
    #合并两段有序链表
    def merge(self, phead1, phead2):
        #一个已空,直接返回另一个
        if phead1 == None:
            return phead2
        if phead2==None:
            return phead1
        #虚拟表头
        dummy_head=ListNode(0)
        cur=dummy_head
        #两个表都不为空
        while phead1 and phead2:
            if phead1.val <= phead2.val:
                cur.next=phead1
                #只移动取值的指针
                phead1=phead1.next
            else:
                cur.next=phead2
                phead2=phead2.next
            #指针后移
            cur=cur.next
        #哪个链表有剩,直接连在后面
        if phead1:
            cur.next=phead1
        if phead2:
            cur.next=phead2
        return dummy_head.next
        
    def sortInList(self , head: ListNode) -> ListNode:
        # 1、归并排序:分治+双指针 
        #链表为空或只有一个元素,直接有序
        if head==None or head.next==None:
            return head
        #前序指针指向mid的前一个位置
        left=head
        #慢指针指向中间位置
        mid=head.next
        #快指针,每次走2步
        right=head.next.next
        #右指针到链表尾时,mid指针在链表中间
        while right and right.next:
            left=left.next
            mid=mid.next
            right=right.next.next
        #前序指针指向左端最右的一个节点,从这里断开
        left.next=None
        #分成2段排序,合并排序好的段
        return self.merge(self.sortInList(head), self.sortInList(mid))

2、链表转数组
链表转数组
数组排序
排序后的数组转链表
时间复杂度:O(nlogn)sort函数一般为优化后的快速排序,复杂度为O(nlogn)
空间复杂度:O(n),存储链表元素值的辅助数组长度n

class Solution:
 def sortInList(self , head: ListNode) -> ListNode:
# 2、转为数组排序
        #为空处理
#         if head is None or head.next is None:
#             return head
#         p=head
#         nums=[]
#         #遍历链表,将结点值加入数组
#         while p:
#             nums.append(p.val)
#             p=p.next
#         #数组排序
#         nums.sort()
#         p=head
#         #遍历数组,将排序后的值加入链表
#         for i in range(len(nums)):
#             p.val=nums[i]
#             p=p.next
#         return head
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值