单项链表是许多高级数据结构的基础,这些高级数据结构有queue、list、stack等等。一般情况下,我们不会直接用单向链表解决现实问题,而是借助高级数据结构来解决现实问题。
本文将通过以下几方面来介绍单向链表:
Singly linked lists contain nodes which have a data field as well as 'next' field, which points to the next node in line of nodes. Operations that can be performed on singly linked lists include insertion, deletion and traversal.
以上定义说明,单向链表是由一个一个的链表节点串联而成,每个链表节点由2部分组成:数据部分和指向下一个节点部分,如下图所示:
组成链表的操作如下所示:
单向链表有以下几点特性:
以下是Python版本的链表,我们定义了一个单向链表类型SinglyLinkedList
,它有以下属性:
head
指向了表头,能够方便地让你从表头开始遍历整个链表或者删除表头节点tail
指向了表尾,能够方便地让你向表尾增加新的节点count
是指链表的节点数,可以用它来判断链表是否为空除此之外,以下代码还定义了4个与单向链表相关的操作:
add_to_tail
,向表尾增加新的节点remove_from_head
,删除表头empty
,判断链表是否为空链表print_all
,遍历并打印链表上所有节点class SinglyLinkedListNode:
def __init__(self, key, val):
self.next = None
self.key = key
self.value = val
def __str__(self):
return f'{self.key},{self.value}'
class SinglyLinkedList:
def __init__(self):
self.head = None
self.tail = None
self.count = 0
def add_to_tail(self, key, val):
new_node = SinglyLinkedListNode(key, val)
if self.count == 0:
self.tail = self.head = new_node
else:
self.tail.next = new_node
self.tail = new_node
self.count += 1
def remove_from_head(self):
head = self.head
self.head = self.head.next
self.count -= 1
if self.empty():
self.tail = None
return head
def find(self, key):
current_node = self.head
while current_node is not None:
if current_node.key == key:
return current_node
current_node = current_node.next
return None
def insert(self, key, value):
node = self.find(key)
if node is None:
self.add_to_tail(key, value)
return 1
else:
node.value = value
return 0
def remove(self, key):
previous_node = current_node = self.head
while current_node is not None:
if current_node.key == key:
if previous_node == current_node:
return self.remove_from_head()
else:
previous_node.next = current_node.next
current_node.next = None
return current_node
previous_node = current_node
current_node = current_node.next
return None
def empty(self):
return self.count == 0
def print_all(self):
current_node = self.head
while current_node:
print(current_node.value)
current_node = current_node.next
以下是以上单向链表的用法:
single_linked_list = SinglyLinkedList()
single_linked_list.add_to_tail(1, 1)
single_linked_list.add_to_tail(10, 10)
single_linked_list.add_to_tail(90, 90)
single_linked_list.add_to_tail(100, 100)
single_linked_list.add_to_tail(2, 2)
single_linked_list.print_all()
输出结果如下所示:
1
10
90
100
2
接下来,让我们看看以上定义的每一种方法,它们的空间复杂度和时间复杂度是多少。
add_to_tail
用于向表尾增加新节点,它的空间复杂度是O(1),而时间复杂度是O(1)remove_from_head
,删除表头,它的空间复杂度是O(1),而时间复杂度是O(1)empty
用于判断链表是否不包含任何节点,它的空间复杂度是O(1),而时间复杂度是O(1)print_all
用于顺序遍历整个链表,它的空间复杂度是O(1),而时间复杂度是O(n)从以上分析可知,除了遍历的时间复杂度与链表的节点个数成正比,其它操作的时间复杂度均是O(1)。另外,单向链表非常不适合反向遍历,为了解决这个问题,计算机的先驱们发明了另外一种类似的数据结构-双向链表。
{{ c.user.name }}
{{ c.content }}