在Python中使用关联列表数据结构
在掌握了Python中所有的线性数据结构之后,我们几乎已经到了这个系列的终点。最后,我们有一个最复杂的线性数据结构,即强大的**关联列表。**😏

正如备忘录中所说的,头部是链接列表中最不可或缺的部分!
好吧,关联列表并不像你想象的那么复杂。不过,它的功能非常强大。
关于Python中不同类型的数据结构的更多背景,请查看下面的文章。
关联列表。简介
链接列表是一种线性数据结构。它们是一个数据序列,通过链接或指针 连接在一起。
链接列表是一个节点链,通过链接连接在一起。每个节点(链接列表的基本块)都包含以下字段。
- 数据-> 要存储在节点中的项目。
- 下一个-> 到下一个节点的链接或引用。

在一个链接列表中,第一个节点被称为头,最后一个节点是由下一个指向空值的条件决定的。

链接列表的用途
- 由于其动态大小的分配和插入/删除的便利性,链接列表被应用于很多的使用案例。
- 它们被用来实现很多复杂的数据结构,比如图中的邻接列表。
- 它们被用于操作系统中的生命周期管理。
- 音乐应用中的播放列表是用双链表实现的。
- 区块链,一种用于加密货币和分类账的复杂数据结构,其核心是使用一个链接列表。
实现关联列表
有两种主要类型的关联列表。
- 单一关联列表
- 双重链接列表
单一关联列表
在下面的例子中,我们将用Python从头开始实现一个单链表。这包含以下方法。
ll.search(head, data)-> 在链接列表中搜索给定的元素。ll.print_list()-> 打印链接列表。ll.size()-> 返回链接列表的长度。ll.insert(ele)-> 将给定的节点插入到链表中。ll.delete(data)-> 从链表中删除给定元素。
class Node(object):
def __init__(self, data):
self.data = data
self.next = None
# Class to create a Linked List
class LinkedList(object):
def __init__(self, head=None):
self.head = head
# Search an element and print its index
def search(self, head, data, index):
if head.data == data:
print (index)
else:
# Make recursive calls
if head.next:
return self.search(head.next, data, index+1)
else:
raise ValueError("Node not in linked list")
# Print the linked list
def print_list(self):
if self.head == None:
raise ValueError("List is empty")
current = self.head
while(current):
print (current.data, end=" ")
current = current.next
print ('\n')
# Find length of Linked List
def size(self):
if self.head == None:
return 0
size = 0
current = self.head
while(current):
size += 1
current = current.next
return size
# Insert a node in a linked list
def insert(self, data):
node = Node(data)
if not self.head:
self.head = node
else:
node.next = self.head
self.head = node
# Delete a node in a linked list
def delete(self, data):
if not self.head:
return
temp = self.head
# Check if head node is to be deleted
if head.data == data:
head = temp.next
print ("Deleted node is " + str(head.data))
return
while(temp.next):
if (temp.next.data == data):
print ("Node deleted is " + str(temp.next.data))
temp.next = temp.next.next
return
temp = temp.next
print ("Node not found")
return
双链表
一个双链表与单链表相似。它的不同之处在于,它还包含一个到前一个节点的链接。

我们为双链表的数据结构实现以下方法。
dll.addNodeLast(x)-> 在链表的右端增加一个节点。dll.insertNode(pos, x)-> 在指定的位置增加一个节点。dll.removeNode(x)-> 移除指定的节点。dll.showReverse()-> 反向打印链表。dll.show()-> 打印链表。
class Node:
def __init__(self, val):
self.value = val
self.next = None
self.prev = None
class DoublyList:
def __init__(self, val):
self.head = Node(val)
self.tail = self.head
def addNodeLast(self, val):
current = self.head
while current.next != None:
current = current.next
newNode = Node(val)
current.next = newNode
newNode.prev = current
self.tail = newNode
def insertNode(self, val, newVal):
if self.tail.value == val:
self.addNodeLast(newVal)
elif self.head.value == val:
newNode = Node(newVal)
newNode.next = self.head.next
newNode.prev = self.head
newNode.next.prev = newNode
self.head.next = newNode
else:
current = self.head.next
while current.value != val:
current = current.next
newNode = Node(newVal)
newNode.next = current.next
newNode.next.prev = newNode
newNode.prev = current
current.next = newNode
def removeNode(self, val):
if self.head.value == val:
self.head = self.head.next
self.head.prev = None
elif self.tail.value == val:
self.tail = self.tail.prev
self.tail.next = None
else:
current = self.head.next
while current.value != val:
current = current.next
current.prev.next = current.next
current.next.prev = current.prev
def showReverse(self):
current = self.tail
while current != None:
print(current.value)
current = current.prev
def show(self):
current = self.head
while current != None:
print(current.value)
current = current.next
练习关联列表
首先,尝试实现如上所示的关联列表,然后尝试运行它们。一旦你掌握了实现方法,就可以尝试给定的问题集来掌握关联列表。
- 合并两个排序的列表 -LeetCode
- 从列表末端移除第n个节点--LeetCode
- 旋转列表 -LeetCode
- Palindrome Linked List -LeetCode
- 从二维矩阵中构建一个双链列表 -GeeksforGeeks
- 反转一个双链表 -GeeksforGeeks
总结
关联列表可能有点吓人,但是一旦你理解了它们,你就会发现理解树、图和其他类似的数据结构也很容易了恭喜你,在本系列文章结束时,你已经掌握了线性数据结构。