返回

从0开始学习数据结构-线性链表的基本算法②

后端

  1. 在链表中插入元素

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