在数据结构中,链表是一种非常基础且重要的线性结构。与数组不同,链表通过节点之间的引用(指针)来组织数据,具有动态内存分配、插入和删除效率高等优点。
本文将围绕一个完整的单链表(Singly Linked List) 实现进行讲解,并详细说明每个方法的逻辑与作用,帮助你从零构建对链表的理解。
class Node:
def __init__(self, item=None, next=None):
self.item = item
self.next = next
功能说明:
class SingleLinkList:
def __init__(self):
self.__head = Node() # 初始化头节点
功能说明:
def is_empty(self):
return self.__head.next is None
功能说明:
def get_length(self):
length = 0
p = self.__head.next
while p is not None:
p = p.next
length += 1
return length
功能说明:
def get(self, pos):
if pos < 0:
raise IndexError("Index out of range")
p = self.__head.next
index = 0
while index < pos and p is not None:
p = p.next
index += 1
if p is None:
raise IndexError(f"Index {pos} out of range")
return p.item
功能说明:
示例:
sll = SingleLinkList()
sll.insert_head(10)
sll.insert_head(20)
sll.insert_head(30)
print(sll.get(0)) # 输出 30
print(sll.get(2)) # 输出 10
def get_first_index(self, item):
p = self.__head.next
index = 0
while p is not None and not (p.item == item):
p = p.next
index += 1
if p is not None:
return index
else:
return -1
功能说明:
示例:
sll = SingleLinkList()
sll.insert_head(10)
sll.insert_head(20)
sll.insert_head(30)
print(sll.get_first_index(20)) # 输出 1
print(sll.get_first_index(50)) # 输出 -1
def insert_head(self, item):
p = self.__head
new_node = Node(item)
new_node.next = p.next
p.next = new_node
功能说明:
示例:
sll.insert_head(10)
sll.insert_head(20)
sll.travel() # 输出: 20 10
def insert_tail(self, item):
p = self.__head
new_node = Node(item)
while p.next is not None:
p = p.next
p.next = new_node
功能说明:
示例:
sll.insert_tail(30)
sll.insert_tail(40)
sll.travel() # 输出: 30 40
def insert(self, pos, item):
if pos < 0:
self.insert_head(item)
return
p = self.__head
index = 0
while p is not None and index < pos:
p = p.next
index += 1
if p is None:
self.insert_tail(item)
else:
new_node = Node(item)
new_node.next = p.next
p.next = new_node
功能说明:
示例:
sll.insert(2, 25) # 插入到第三个位置
sll.travel() # 输出: 20 10 25 30 40
def remove(self, pos):
if pos < 0:
raise IndexError("Index out of range")
p = self.__head
index = 0
while p is not None and index < pos:
p = p.next
index += 1
if p is None:
raise Exception("Index out of range")
p.next = p.next.next
功能说明:
示例:
sll.remove(2) # 删除第3个节点(即25)
sll.travel() # 输出: 20 10 30 40
def travel(self):
p = self.__head.next
while p is not None:
print(p.item, end=' ')
p = p.next
print()
功能说明:
操作 | 方法名 | 时间复杂度 | 说明 |
---|---|---|---|
判空 | is_empty() | O(1) | 检查是否有数据节点 |
获取长度 | get_length() | O(n) | 遍历链表计数 |
获取元素 | get(pos) | O(n) | 定位并返回对应节点数据 |
查找索引 | get_first_index(item) | O(n) | 返回首次出现的位置 |
头部插入 | insert_head(item) | O(1) | 插入到第一个节点 |
尾部插入 | insert_tail(item) | O(n) | 需要遍历到末尾 |
中间插入 | insert(pos, item) | O(n) | 定位后插入 |
删除节点 | remove(pos) | O(n) | 定位后跳过目标节点 |
遍历输出 | travel() | O(n) | 逐个打印 |
sll = SingleLinkList()
sll.insert_head(10)
sll.insert_head(20)
sll.insert_head(30)
sll.insert_head(40)
sll.insert_head(50)
print("初始链表:")
sll.travel() # 输出: 50 40 30 20 10
sll.insert(3, 250)
print("插入 250 到位置 3:")
sll.travel() # 输出: 50 40 30 250 20 10
sll.remove(3)
print("删除位置 3 的节点:")
sll.travel() # 输出: 50 40 30 20 10
print("查找 20 的位置:", sll.get_first_index(20)) # 输出: 3
print("获取位置 2 的元素:", sll.get(2)) # 输出: 30
单链表作为一种基础的数据结构,虽然在随机访问上不如数组高效,但在频繁插入和删除场景下具有明显优势。掌握链表的插入、删除、查找、遍历等基本操作,是学习更复杂数据结构(如栈、队列、图、树)的基础。
学习数据结构和算法的过程就像在黑暗中摸索前行,一开始你可能看不清方向,也看不到终点。但请相信,每一步看似笨拙的尝试,其实都在悄悄为你打下基础。那些你花时间理解的每一行代码,每一个你修复的 bug,每一次你重新思考逻辑的过程,都会成为你未来面对更复杂问题时的底气。你不需要一开始就写出完美的代码,只要你在不断尝试、不断改进,就已经走在了成为优秀开发者的路上。愿你始终保有信心,在编程的路上越走越稳,越走越远。你不是不行,只是还在成长。