【插入排序】Leetcode 147对单链表进行插入排序

该文章详细介绍了如何使用插入排序算法对链表进行排序,包括插入排序的基本步骤、链表操作的特性以及Python代码实现。通过创建哑节点辅助操作,从链表头开始遍历,寻找合适插入位置,最后返回排序后链表的头节点。
摘要由CSDN通过智能技术生成

leetcode 147 leetcode 147

题目描述:
给定单个链表的头 head ,使用 插入排序 对链表进行排序,并返回 排序后链表的头 。

插入排序 算法的步骤:

插入排序是迭代的,每次只移动一个元素,直到所有元素可以形成一个有序的输出列表。
每次迭代中,插入排序只从输入数据中移除一个待排序的元素,找到它在序列中适当的位置,并将其插入。
重复直到所有输入数据插入完为止。
下面是插入排序算法的一个图形示例。部分排序的列表(黑色)最初只包含列表中的第一个元素。每次迭代时,从输入数据中删除一个元素(红色),并就地插入已排序的列表中。

对链表进行插入排序。

python对列表or数组进行插入排序的代码:

def insert_sort(nums):
    size = len(nums)
    for i in range(1,size):
      for j in range(i,0,-1):
        #只要后面的比前面的元素严格小,就交换他们之间的位置
        if nums[j-1] < nums[j]:
           nums[j], nums[j-1] = nums[j-1], nums[j]
        else:
           break

对于链表的插入排序操作,思想与数组的插入排序相同,只是对链表的操作不同。官方的题解说明如下:官方题解

方法一:从前往后找插入点

插入排序的基本思想是,维护一个有序序列,初始时有序序列只有一个元素,每次将一个新的元素插入到有序序列中,将有序序列的长度增加 111,直到全部元素都加入到有序序列中。

如果是数组的插入排序,则数组的前面部分是有序序列,每次找到有序序列后面的第一个元素(待插入元素)的插入位置,将有序序列中的插入位置后面的元素都往后移动一位,然后将待插入元素置于插入位置。

对于链表而言,插入元素时只要更新相邻节点的指针即可,不需要像数组一样将插入位置后面的元素往后移动,因此插入操作的时间复杂度是 O(1)O(1)O(1),但是找到插入位置需要遍历链表中的节点,时间复杂度是 O(n)O(n)O(n),因此链表插入排序的总时间复杂度仍然是 O(n2)O(n^2)O(n
2
),其中 nnn 是链表的长度。

对于单向链表而言,只有指向后一个节点的指针,因此需要从链表的头节点开始往后遍历链表中的节点,寻找插入位置。

对链表进行插入排序的具体过程如下。

首先判断给定的链表是否为空,若为空,则不需要进行排序,直接返回。

创建哑节点 dummyHead,令 dummyHead.next = head。引入哑节点是为了便于在 head 节点之前插入节点。

维护 lastSorted 为链表的已排序部分的最后一个节点,初始时 lastSorted = head。

维护 curr 为待插入的元素,初始时 curr = head.next。

比较 lastSorted 和 curr 的节点值。

若 lastSorted.val <= curr.val,说明 curr 应该位于 lastSorted 之后,将 lastSorted 后移一位,curr 变成新的 lastSorted。

否则,从链表的头节点开始往后遍历链表中的节点,寻找插入 curr 的位置。令 prev 为插入 curr 的位置的前一个节点,进行如下操作,完成对 curr 的插入:

lastSorted.next = curr.next
curr.next = prev.next
prev.next = curr

令 curr = lastSorted.next,此时 curr 为下一个待插入的元素。

重复第 5 步和第 6 步,直到 curr 变成空,排序结束。

返回 dummyHead.next,为排序后的链表的头节点。

class Solution:
    def insertionSortList(self, head: ListNode) -> ListNode:
        if not head:
            return head
        
        dummyHead = ListNode(0)
        dummyHead.next = head
        lastSorted = head
        curr = head.next

        while curr:
            if lastSorted.val <= curr.val:
                lastSorted = lastSorted.next
            else:
                prev = dummyHead
                while prev.next.val <= curr.val:
                    prev = prev.next
                lastSorted.next = curr.next
                curr.next = prev.next
                prev.next = curr
            curr = lastSorted.next
        
        return dummyHead.next

作者:力扣官方题解
链接:https://leetcode.cn/problems/insertion-sort-list/solutions/491124/dui-lian-biao-jin-xing-cha-ru-pai-xu-by-leetcode-s/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

插入排序示意图
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值