python创建一个有序链表_有序链表

本文介绍了有序链表的基本概念及其实现方法,包括创建、添加、删除等操作,并详细解释了搜索过程如何利用有序特性提高效率。

有序链表:17,26,31,54,77,93。由于 17 是最小项,它占据第一位置。同样,由于 93 是最大的,它占据最后的位置。

排序通常是升序或降序。

有序链表的抽象数据类型

下面给出了一些可能的无序链表操作:

操作

描述

返回值

OrderedList

创建一个新的空链表,不需要参数

返回一个空链表

add(item)

向链表中添加一个新项,需要 item 作为参数

不返回任何内容

remove(item)

从链表中删除该项,需要 item 作为参数并修改链表

search(item)

搜索链表中的项目,需要 item 作为参数

返回一个布尔值

isEmpty()

检查链表是否为空,不需要参数

返回布尔值

size()

返回链表中的项数,不需要参数

返回一个整数

append(item)

将一个新项添加到链表的末尾,使其成为集合中的最后一项,需要 item 作为参数

不返回任何内容

index(item)

返回项在链表中的位置,需要 item 作为参数

返回索引

pop()

删除链表中的最后一个项

返回删除项

pop(pos)

删除位置 pos 处的项,需要 pos 作为参数

返回删除项

python实现有序链表

创建有序链表

class OrderedList:

def __init__(self):

self.head = None

isEmpty、和size、remove方法同无序链表的实现方式一致,search、add。

有序链表搜索

搜索无序链表时需要我们一次遍历一个节点,直到找到我们正在寻找的节点或者没找到节点(None)。事实证明,相同的方法在有序链表中也有效。然而,在项不在链表中的情况下,我们可以利用该顺序来尽快停止搜索。

下图展示了搜索45的过程:从链表的头部开始遍历,首先与 17 进行比较。由于 17 不是我们正在寻找的项,移动到下一个节点 26 。再次,这不是我们想要的,继续到 31,然后再到 54 。在这一点上,有一些不同。由于 54 不是我们正在寻找的项,我们以前的方法是继续向前迭代。然而,由于这是有序列表,一旦节点中的值变得大于我们正在搜索的项,搜索就可以停止并返回 False 。该项不可能存在于后面的链表中。

aa198f08a199

有序链表搜索

def search(self,item):

current = self.head

found = False

stop = False

while current != None and not found and not stop:

if current.getData() == item

found = True

else:

if current.getData > item:

stop = True

else:

current = current.getNext()

return found

有序链表中添加项

对于无序列表,add 方法可以简单地将新节点放置在链表的头部。 这是最简单的访问点。 不幸的是,这将不再适用于有序列表。需要在现有的有序列表中查找新项所属的特定位置。

aa198f08a199

有序链表添加项

如图,假设我们有由 17,26,54,77,93 组成的有序列表,并且我们要添加值31 。 add 方法必须确定新项属于 26 与 54 之间。

def add(self,item):

current = self.head

previous = None

stop = False

while current != None and not stop:

if current.getData() > item:

stop = True

else:

previous = current

current = current.getNext()

temp = Node(item)

if previous == None:

temp.setNext(self.head)

self.head = temp

else:

temp.setNext(current)

previous.setNext(temp)

<think>我们有两个有序链表,需要将它们合并为一个新的有序链表。这里我们采用迭代法,因为它的空间复杂度为$O(1)$,且代码清晰易懂。 迭代法思路: 1. 创建一个哑节点(dummy)作为新链表的起始点,这样可以避免处理头节点为空的边界情况。 2. 使用一个指针cur指向当前新链表的最后一个节点(初始时指向dummy)。 3. 同时遍历两个链表l1和l2,比较当前两个链表节点的值,将较小值的节点连接到cur的后面,并移动该链表的指针和cur指针。 4. 当其中一个链表遍历完时,将另一个链表剩余部分直接连接到新链表的末尾。 5. 返回dummy.next,即新链表的头节点。 注意:两个链表都是升序排列,合并后的链表也必须是升序。 根据引用[2]和[3]中的代码,我们实现如下:</think>### Python实现两个有序链表的有序合并 以下是使用迭代法实现两个有序链表合并的Python代码,这是最优的实现方法(时间复杂度$O(n+m)$,空间复杂度$O(1)$): ```python class ListNode: def __init__(self, val=0, next=None): self.val = val self.next = next def mergeTwoLists(l1: ListNode, l2: ListNode) -> ListNode: # 创建哑节点作为新链表起点 dummy = ListNode() cur = dummy # 当前指针 # 同时遍历两个链表 while l1 and l2: if l1.val <= l2.val: cur.next = l1 l1 = l1.next else: cur.next = l2 l2 = l2.next cur = cur.next # 移动新链表指针 # 连接剩余部分(其中一个链表已遍历完) cur.next = l1 if l1 else l2 return dummy.next # 返回哑节点的下一个(真正头节点) # 测试用例 def create_list(nums): dummy = ListNode() cur = dummy for num in nums: cur.next = ListNode(num) cur = cur.next return dummy.next def print_list(head): res = [] while head: res.append(head.val) head = head.next print(res) # 测试 l1 = create_list([1, 3, 5]) l2 = create_list([2, 4, 6]) merged = mergeTwoLists(l1, l2) print_list(merged) # 输出: [1, 2, 3, 4, 5, 6] ``` ### 代码解析 1. **哑节点(dummy)的作用** - 作为新链表的起始占位符,避免处理空链表的特殊情况 - 通过`dummy.next`返回真正的头节点 - 简化指针操作,统一处理逻辑[^2][^3] 2. **核心循环逻辑** - `while l1 and l2`:确保两个链表都有节点时才比较 - `l1.val <= l2.val`:优先选择较小节点(相同元素时保持原顺序) - 每次只移动被选中链表的指针和新链表指针 3. **剩余部分处理** - `cur.next = l1 if l1 else l2`:将未遍历完的链表直接接入尾部 - 因为剩余部分本身有序,无需额外操作[^3][^4] 4. **时间复杂度分析** - 最坏情况:$O(n+m)$,其中$n$和$m$是两个链表的长度 - 每个节点只被访问一次 ### 执行过程示例 ```mermaid graph LR A[l1:1→3→5] --> B[比较节点值] C[l2:2→4→6] --> B B -->|1<2| D[新链表:1] B -->|3>2| E[新链表:1→2] B -->|3<4| F[新链表:1→2→3] B -->|5>4| G[新链表:1→2→3→4] H[连接剩余部分:5→6] I[最终结果:1→2→3→4→5→6] ``` ### 递归法实现(备选) 虽然递归法代码更简洁,但空间复杂度为$O(n+m)$(递归栈空间): ```python def mergeTwoLists(l1: ListNode, l2: ListNode) -> ListNode: if not l1: return l2 if not l2: return l1 if l1.val <= l2.val: l1.next = mergeTwoLists(l1.next, l2) return l1 else: l2.next = mergeTwoLists(l1, l2.next) return l2 ``` > 实际开发中推荐迭代法,避免递归深度过大导致栈溢出问题[^1][^5]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值