返回
从0开始学习数据结构-线性链表的基本算法②
后端
2023-09-10 12:12:40
- 在链表中插入元素
2.1 头部插入
头部插入是将新元素插入到链表的头部,是最简单的一种插入操作。
def insert_at_head(self, value):
"""
在链表头部插入一个元素。
Args:
value: 要插入的元素的值。
"""
# 创建一个新的节点,并将值存储在该节点中。
new_node = Node(value)
# 将新节点的下一个节点指向当前的头节点。
new_node.next = self.head
# 将新节点设置为头节点。
self.head = new_node
2.2 尾部插入
尾部插入是将新元素插入到链表的尾部。
def insert_at_tail(self, value):
"""
在链表尾部插入一个元素。
Args:
value: 要插入的元素的值。
"""
# 如果链表为空,则将新元素插入到链表的头部。
if self.head is None:
self.insert_at_head(value)
return
# 否则,遍历链表,找到最后一个节点。
current_node = self.head
while current_node.next is not None:
current_node = current_node.next
# 创建一个新的节点,并将值存储在该节点中。
new_node = Node(value)
# 将新节点的下一个节点指向最后一个节点。
current_node.next = new_node
2.3 中间插入
中间插入是将新元素插入到链表的中间。
def insert_at_index(self, index, value):
"""
在链表的指定位置插入一个元素。
Args:
index: 要插入的位置。
value: 要插入的元素的值。
"""
# 如果索引为0,则将新元素插入到链表的头部。
if index == 0:
self.insert_at_head(value)
return
# 如果索引大于或等于链表的长度,则将新元素插入到链表的尾部。
if index >= self.length():
self.insert_at_tail(value)
return
# 否则,遍历链表,找到要插入位置的前一个节点。
current_node = self.head
for i in range(index - 1):
current_node = current_node.next
# 创建一个新的节点,并将值存储在该节点中。
new_node = Node(value)
# 将新节点的下一个节点指向要插入位置的节点。
new_node.next = current_node.next
# 将新节点插入到要插入位置的前一个节点之后。
current_node.next = new_node
3. 从链表中删除元素
3.1 删除头部元素
删除头部元素是最简单的一种删除操作。
def delete_at_head(self):
"""
删除链表的头部元素。
"""
# 如果链表为空,则返回。
if self.head is None:
return
# 将头节点指向下一个节点。
self.head = self.head.next
3.2 删除尾部元素
删除尾部元素的步骤如下:
def delete_at_tail(self):
"""
删除链表的尾部元素。
"""
# 如果链表为空,则返回。
if self.head is None:
return
# 如果链表只有一个节点,则将头节点指向空。
if self.head.next is None:
self.head = None
return
# 否则,遍历链表,找到最后一个节点的前一个节点。
current_node = self.head
while current_node.next.next is not None:
current_node = current_node.next
# 将最后一个节点的前一个节点的下一个节点指向空。
current_node.next = None
3.3 删除中间元素
删除中间元素的步骤如下:
def delete_at_index(self, index):
"""
删除链表的指定位置的元素。
Args:
index: 要删除的位置。
"""
# 如果索引为0,则删除头部元素。
if index == 0:
self.delete_at_head()
return
# 如果索引大于或等于链表的长度,则返回。
if index >= self.length():
return
# 否则,遍历链表,找到要删除位置的前一个节点。
current_node = self.head
for i in range(index - 1):
current_node = current_node.next
# 将要删除位置的节点的下一个节点指向要删除位置的后一个节点。
current_node.next = current_node.next.next
4. 在链表中查找元素
在链表中查找元素的步骤如下:
def find(self, value):
"""
在链表中查找一个元素。
Args:
value: 要查找的元素的值。
Returns:
如果找到该元素,则返回该元素的索引,否则返回-1。
"""
# 遍历链表,找到该元素。
current_node = self.head
index = 0
while current_node is not None:
if current_node.value == value:
return index
current_node = current_node.next
index += 1
# 如果没有找到该元素,则返回-1。
return -1
5. 对链表进行排序
对链表进行排序的步骤如下:
def sort(self):
"""
对链表进行排序。
"""
# 如果链表为空或只有一个节点,则返回。
if self.head is None or self.head.next is None:
return
# 将链表拆分为两个子链表。
mid = self.length() // 2
left_sublist = LinkedList()
right_sublist = LinkedList()
current_node = self.head
for i in range(mid):
left_sublist.append(current_node.value)
current_node = current_node.next
for i in range(mid, self.length()):
right_sublist.append(current_node.value)
# 对两个子链表进行排序。
left_sublist.sort()
right_sublist.sort()
# 将两个子链表合并为一个排序后的链表。
self.head = merge(left_sublist.head, right_sublist.head)
def merge(left_node, right_node):
"""
将两个链表合并为一个排序后的链表。
Args:
left_node: 左链表的头节点。
right_node: 右链表的头节点。
Returns:
合并后的链表的头节点。
"""
# 如果两个链表都为空,则返回空链表。
if left_node is None and right_node is None:
return None
# 如果左链表为空,则返回右链表。
if left_node is None:
return right_node
# 如果右链表为空,则返回左链表。
if right_node is None:
return left_node
# 将两个链表的头节点的值进行比较,较小的值作为合并后的链表的头节点。
if left_node.value < right_node.value:
head = left_node
left_node = left_node.next
else:
head = right_node
right_node = right_node.next
# 递归地将两个链表的剩余部分合并到合并后的链表中。
head.next = merge(left_node, right_node)
# 返回合并后的链表的头节点。
return head
6. 遍历链表
遍历链表的步骤如下:
def traverse(self):
"""
遍历链表。
"""
# 创建一个指针指向链表的头节点。
current_node = self.head
# 循环遍历链表,直到指针指向空。
while current_node is not None:
# 访问当前节点的值。
print