python 实现单链表的基础操作:插入、删除、遍历、获取元素等

ゞ 浴缸里的玫瑰 2022-11-17 13:37 651阅读 0赞

回顾一下单链表的知识,并用python实现单链表的基础操作:插入,删除,遍历,判空,清空链表,求长度, 获取元素,判断元素是否存在等。

链表通过指针将零散的内存块连接在一起,链表的每个节点存储有该节点的值和下一个节点的地址。

链表的第一个节点为基节点,最后一个节点是尾节点。头节点记录了链表的基地址,最后一个节点的指针指向None。

链表的插入,删除操作的时间复杂度都是O(1), 单链表的遍历时间复杂度是O(n)。

在这里插入图片描述

定义链表的同时也要定义链表节点Node,节点存储值item和指针_next, 也可理解为引用,指向的是下一个节点的地址。

看了下王争老师的代码,对链表的插入和删除操作考虑都比较全面。

动手写了一遍之后,发现根据某个值删除节点的操作有点意思。

因为不知道这个值在哪里,所以需要挨个遍历链表,删除该节点时,将删除的节点的值赋值为下一个节点的值,然后删除下一个节点。

就像是如果要我死,就让我变成A,然后杀了A的原主。

我没有了,而A还活着。但其实我就是A。

  1. def delete_by_value(self, value: int):
  2. if not self.head or not value:
  3. return
  4. fake_head = Node(-1)
  5. fake_head.next = self.head
  6. prev, current = fake_head, self.head
  7. while current:
  8. if current.item != value:
  9. prev.next = current
  10. prev = prev.next
  11. current = current.next
  12. if prev.next: # current.item == value
  13. prev.next = prev.next.next
  14. self.head = fake_head.next

全部代码

  1. class Node:
  2. """链表节点"""
  3. def __init__(self, item: int, next=None):
  4. self.item = item
  5. self.next = next
  6. class LinkedList:
  7. """链表"""
  8. def __init__(self):
  9. self.head = None
  10. def find_by_value(self, value: int):
  11. # 根据值查找节点
  12. p = self.head
  13. while p and p.item != value:
  14. p = p.next
  15. return p
  16. def find_by_index(self, position: int):
  17. # 根据索引位置查找节点,需要挨个遍历
  18. p = self.head
  19. index = 0
  20. while p and index != position:
  21. p = p.next
  22. index += 1
  23. return p
  24. def insert_value_to_head(self, value: int):
  25. node = Node(value)
  26. self.insert_node_to_head(node)
  27. def insert_node_to_head(self, node):
  28. if node:
  29. node.next = self.head
  30. self.head = node
  31. def insert_node_after(self, node, new_node):
  32. if not node or not new_node:
  33. return
  34. new_node.next = node.next
  35. node.next = new_node
  36. def insert_value_after(self, node, value):
  37. new_node = Node(value)
  38. self.insert_node_after(node, new_node)
  39. def insert_node_before(self, node, new_node):
  40. if not self.head or not node or not new_node:
  41. return
  42. if node == self.head:
  43. self.insert_node_to_head(new_node)
  44. return
  45. p = self.head
  46. while p and p.next != node:
  47. p = p.next
  48. if not p:
  49. return
  50. new_node.next = node
  51. p.next = new_node
  52. def insert_value_before(self, value: int, node):
  53. new_node = Node(value)
  54. self.insert_node_before(node, new_node)
  55. def delete_by_node(self, node):
  56. # 删除某个节点
  57. if not self.head or not node:
  58. return
  59. # 不是最后一个节点,可以直接删除, 删除的复杂度为O(1)
  60. if node.next:
  61. node.item = node.next.item
  62. node.next = node.next.next
  63. p = self.head
  64. while p and p.next != node:
  65. p = p.next
  66. if not p:
  67. return
  68. p.next = node.next
  69. def delete_by_value(self, value: int):
  70. # 删除某个值对应的节点
  71. if not self.head or not value:
  72. return
  73. fake_head = Node(-1)
  74. fake_head.next = self.head
  75. prev, current = fake_head, self.head
  76. while current:
  77. if current.item != value:
  78. prev.next = current
  79. prev = prev.next
  80. current = current.next
  81. if prev.next: # current.item == value
  82. prev.next = prev.next.next
  83. self.head = fake_head.next
  84. def __repr__(self):
  85. # 打印链表,重写repr或者str函数
  86. a = []
  87. p = self.head
  88. while p:
  89. a.append(p.item)
  90. p = p.next
  91. return " ".join(map(str, a))
  92. if __name__ == '__main__':
  93. l = LinkedList()
  94. for i in range(10):
  95. l.insert_value_to_head(i)
  96. node = l.find_by_value(5)
  97. l.insert_value_before(20, node)
  98. l.insert_value_after(node, 24)
  99. print(l)
  100. l.delete_by_value(4)
  101. print(l)

以下是一些基础代码,不知道为什么看代码有点幼稚。

判空

判断链表是否是空链表只需要判断头节点是否为None即可。

如果为None表示头节点没有指向下一个节点。

  1. def is_empty(self):
  2. """判断是否为空链表,头节点为None则是空"""
  3. return self._head is None

求链表长度

从头节点开始遍历,直到最后的空节点None。

  1. def length(self):
  2. """求链表的长度"""
  3. p = self._head
  4. count = 0
  5. while p:
  6. count += 1
  7. p = p._next
  8. return count

向链表尾部追加元素

如果链表是空链表,则该节点为头节点,否则依次遍历到最后一个值p,然后 p._next = node

  1. def append(self, item):
  2. """向链表尾部添加元素, 考虑是否是空链表"""
  3. node = Node(item)
  4. p = self._head
  5. if not p:
  6. self._head = node
  7. else:
  8. while p._next:
  9. p = p._next
  10. p._next = node

向链表头部插入元素

头插法。其实就是把该元素设置为头节点
在这里插入图片描述

  1. def add(self, item):
  2. """向链表头部插入元素"""
  3. node = Node(item)
  4. node._next = self._head
  5. self._head = node

向链表中插入元素

分为头插,尾插,中间插入

插入元素的核心是node._next = pre._next , pre._next = node, 先后次序一定要注意。先让待插入的node指向p._next, 再让p指向node
在这里插入图片描述

  1. def insert(self, position, item):
  2. """向链表中插入元素"""
  3. # 头插 or 尾插 or 中间插入
  4. if position <= 0:
  5. self.add(item)
  6. elif position >= self.length():
  7. self.append(item)
  8. else:
  9. pre = self._head
  10. count = 0
  11. while count < position - 1:
  12. count += 1
  13. pre = pre._next
  14. node = Node(item)
  15. node._next = pre._next
  16. pre._next = node

获取某位置的元素

  1. def get_item(self, position):
  2. """获取某位置的元素"""
  3. if position < 0 or position >= self.length():
  4. return None
  5. p = self._head
  6. count = 0
  7. while count != position:
  8. p = p._next
  9. count += 1
  10. return p.item

判断值是否存在

  1. def exixt_value(self, item):
  2. """某个值是否存在"""
  3. p = self._head
  4. while p:
  5. if p.item == item:
  6. return True
  7. else:
  8. p = p._next
  9. return False

删除元素

删除头节点一行代码即可。
其他位置的需要判断+遍历
在这里插入图片描述

  1. def remove(self, item):
  2. """删除元素"""
  3. p = self._head
  4. pre = None
  5. while p:
  6. if p.item == item:
  7. # 是否头节点
  8. if not pre:
  9. self._head = p._next
  10. else:
  11. pre._next = p._next
  12. break
  13. else:
  14. pre = p
  15. p = p._next

清空链表

  1. def clear(self):
  2. """删除链表"""
  3. self._head = None

链表遍历

  1. def travel(self):
  2. """列表遍历"""
  3. p = self._head
  4. while p:
  5. print(p.item, end=" ")
  6. p = p._next
  7. print()

测试用例

  1. if __name__ == '__main__':
  2. linklist = LinkList()
  3. linklist.append(2)
  4. linklist.append(3)
  5. linklist.append(4)
  6. linklist.append(5)
  7. print(linklist.length()) # 4
  8. linklist.travel() # 2 3 4 5
  9. linklist.add(1)
  10. linklist.add(0)
  11. linklist.travel() # 0 1 2 3 4 5
  12. linklist.insert(2, 8)
  13. linklist.insert(2, 9)
  14. linklist.travel() # 0 1 9 8 2 3 4 5
  15. print(linklist.get_item(2), linklist.get_item(12), linklist.get_item(4)) # 9 None 2
  16. print(linklist.exixt_value(9), linklist.exixt_value(20)) # True False
  17. linklist.remove(9)
  18. linklist.remove(5)
  19. linklist.travel() # 0 1 8 2 3 4
  20. linklist.clear()
  21. linklist.travel() # 空

完整代码

  1. """ 链表基本操作:创建空链表,删除链表,判断是否为空,添加元素,删除元素,遍历,定位,链表长度 """
  2. class Node:
  3. """链表节点初始化"""
  4. def __init__(self, item):
  5. self.item = item
  6. self._next = None
  7. class LinkList:
  8. """链表及其相关操作"""
  9. def __init__(self):
  10. self._head = None
  11. def is_empty(self):
  12. """判断是否为空链表,头节点为None则是空"""
  13. return self._head is None
  14. def length(self):
  15. """求链表的长度"""
  16. p = self._head
  17. count = 0
  18. while p:
  19. count += 1
  20. p = p._next
  21. return count
  22. def append(self, item):
  23. """向链表尾部添加元素, 考虑是否是空链表"""
  24. node = Node(item)
  25. p = self._head
  26. if not p:
  27. self._head = node
  28. else:
  29. while p._next:
  30. p = p._next
  31. p._next = node
  32. def add(self, item):
  33. """向链表头部插入元素"""
  34. node = Node(item)
  35. node._next = self._head
  36. self._head = node
  37. def insert(self, position, item):
  38. """向链表中插入元素"""
  39. # 头插 or 尾插 or 中间插入
  40. if position <= 0:
  41. self.add(item)
  42. elif position >= self.length():
  43. self.append(item)
  44. else:
  45. pre = self._head
  46. count = 0
  47. while count < position - 1:
  48. count += 1
  49. pre = pre._next
  50. node = Node(item)
  51. node._next = pre._next
  52. pre._next = node
  53. def get_item(self, position):
  54. """获取某位置的元素"""
  55. if position < 0 or position >= self.length():
  56. return None
  57. p = self._head
  58. count = 0
  59. while count != position:
  60. p = p._next
  61. count += 1
  62. return p.item
  63. def exixt_value(self, item):
  64. """某个值是否存在"""
  65. p = self._head
  66. while p:
  67. if p.item == item:
  68. return True
  69. else:
  70. p = p._next
  71. return False
  72. def remove(self, item):
  73. """删除元素"""
  74. p = self._head
  75. pre = None
  76. while p:
  77. if p.item == item:
  78. # 是否头节点
  79. if not pre:
  80. self._head = p._next
  81. else:
  82. pre._next = p._next
  83. break
  84. else:
  85. pre = p
  86. p = p._next
  87. def clear(self):
  88. """删除链表"""
  89. self._head = None
  90. def travel(self):
  91. """列表遍历"""
  92. p = self._head
  93. while p:
  94. print(p.item, end=" ")
  95. p = p._next
  96. print()
  97. if __name__ == '__main__':
  98. linklist = LinkList()
  99. linklist.append(2)
  100. linklist.append(3)
  101. linklist.append(4)
  102. linklist.append(5)
  103. print(linklist.length()) # 4
  104. linklist.travel() # 2 3 4 5
  105. linklist.add(1)
  106. linklist.add(0)
  107. linklist.travel() # 0 1 2 3 4 5
  108. linklist.insert(2, 8)
  109. linklist.insert(2, 9)
  110. linklist.travel() # 0 1 9 8 2 3 4 5
  111. print(linklist.get_item(2), linklist.get_item(12), linklist.get_item(4)) # 9 None 2
  112. print(linklist.exixt_value(9), linklist.exixt_value(20)) # True False
  113. linklist.remove(9)
  114. linklist.remove(5)
  115. linklist.travel() # 0 1 8 2 3 4
  116. linklist.clear()
  117. linklist.travel() # 空

发表评论

表情:
评论列表 (有 0 条评论,651人围观)

还没有评论,来说两句吧...

相关阅读