Python 链表
引言
事实上,Python
中的链表比较鸡肋,大多数情况下,我们都无需使用链表,仅使用普通的 list
对象即可。那么,我们为什么要使用链表呢?
有时,我们的数据量很大,并且此时我们需要在列表对象的初始或者中间进行元素插入时,如果我们使用自带的 pop(0)
方法,那么 Python
会遍历整个列表将最开始的元素删除后,将后续所有元素向前移动一位,这样会使得运行效率大幅下降,而如果使用链表进行操作,就可以很好地避免这一情况。
节点 node
是组成链表的元素。如上图所示,节点由一个数据 Data
和一个指针 Pointer
组成。使用如下代码,我们就可以构建一个节点对象:
class Node:
def __init__(self, data):
self.data = data # 当前 node 存放的值
self.next = None # 下一个 node 的地址
这里,节点的 pointer
我们用 next
属性表示。
如上图所示,链表对象有一个起始点位置,记作 root
。使用如下代码我们可以构建一个空的链表对象。
class LinkedList:
def __init__(self):
self.root= None # 当前 Linked List 中没有 node
这里我们使用 root
来表示链表的初始位置,因为此时链表为空,因此 root
属性的值为 None
。
插入第一个数据后的图:
第一个数据插入后,因为它后面没有数据,因此它的指针指向 None
。
插入第二个数据后的图:
当第二个数据插入后,第二个数据 10
的指针就指向第一个数据 5
的位置了。
通过观察,我们可以将向链表开始位置插入数据的方式总结为以下三个步骤:
- 将
data
值赋值给新的node
- 将新的
node
的next
指针指向以前的root
位置。 - 将原来的
root
指向新的new node
位置。
接下来,我们需要往链表中插入数据,这里我们创建一个方法,可以向链表的起始位置插入数据。
class LinkedList:
def __init__(self):
self.root = None
def insertAtBeginning(self, new_data):
new_node = Node(new_data) # 创建 new_node 对象
new_node.next = self.root # new_node 指向 root 位置
self.root = new_node # root 指向 new_node 对象
为了观察插入方法的效果,我们继续创建一个打印的方法用来显示结果。
class LinkedList:
def __init__(self):
self.root = None
def insertAtBeginning(self, new_data):
new_node = Node(new_data)
new_node.next = self.root
self.root = new_node
def printList(self):
temp = self.root
while temp:
print(temp.data, end=' ') # 打印出在当前 node 中的数据
temp = temp.next # 移动到下一个 node
print() # 确保输出到了一个新的行
if __name__ == '__main__':
llist = LinkedList()
llist.insertAtBeginning('fox')
llist.insertAtBeginning('brown')
llist.insertAtBeginning('quick')
llist.insertAtBeginning('the')
llist.printList()
"""
result:
the quick brown fox
"""
至于链表中的在末尾添加元素以及增加和删除元素的操作,大家可以自行尝试。本文仅做抛砖引玉,后续有时间了本人会继续完善。
有兴趣的小伙伴可以阅读该篇文章 Python Linked Lists: Tutorial With Examples。
如果大家觉得有用,就请点个赞吧~