01a1083f82
current._next = node._next in delete_by_node
148 lines
4.1 KiB
Python
148 lines
4.1 KiB
Python
"""
|
||
1) Insertion, deletion and search of singly-linked list;
|
||
2) Assumes int type for data in list nodes.
|
||
|
||
Author: Wenru
|
||
"""
|
||
from typing import Optional
|
||
|
||
|
||
class Node:
|
||
|
||
def __init__(self, data: int, next_node=None):
|
||
self.data = data
|
||
self._next = next_node
|
||
|
||
|
||
class SinglyLinkedList:
|
||
|
||
def __init__(self):
|
||
self._head = None
|
||
|
||
def find_by_value(self, value: int) -> Optional[Node]:
|
||
p = self._head
|
||
while p and p.data != value:
|
||
p = p._next
|
||
return p
|
||
|
||
def find_by_index(self, index: int) -> Optional[Node]:
|
||
p = self._head
|
||
position = 0
|
||
while p and position != index:
|
||
p = p._next
|
||
position += 1
|
||
return p
|
||
|
||
def insert_value_to_head(self, value: int):
|
||
new_node = Node(value)
|
||
self.insert_node_to_head(new_node)
|
||
|
||
def insert_node_to_head(self, new_node: Node):
|
||
if new_node:
|
||
new_node._next = self._head
|
||
self._head = new_node
|
||
|
||
def insert_value_after(self, node: Node, value: int):
|
||
new_node = Node(value)
|
||
self.insert_node_after(node, new_node)
|
||
|
||
def insert_node_after(self, node: Node, new_node: Node):
|
||
if not node or not new_node:
|
||
return
|
||
new_node._next = node._next
|
||
node._next = new_node
|
||
|
||
def insert_value_before(self, node: Node, value: int):
|
||
new_node = Node(value)
|
||
self.insert_node_before(node, new_node)
|
||
|
||
def insert_node_before(self, node: Node, new_node: Node):
|
||
if not self._head or not node or not new_node:
|
||
return
|
||
if self._head == node:
|
||
self.insert_node_to_head(new_node)
|
||
return
|
||
current = self._head
|
||
while current._next and current._next != node:
|
||
current = current._next
|
||
if not current._next: # node is not even in the list
|
||
return
|
||
new_node._next = node
|
||
current._next = new_node
|
||
|
||
def delete_by_node(self, node: Node):
|
||
if not self._head or not node:
|
||
return
|
||
if node._next:
|
||
node.data = node._next.data
|
||
node._next = node._next._next
|
||
return
|
||
# node is the last one or not in the list
|
||
current = self._head
|
||
while current and current._next != node:
|
||
current = current._next
|
||
if not current: # node not in the list
|
||
return
|
||
current._next = node._next
|
||
|
||
def delete_by_value(self, value: int):
|
||
if not self._head or not value:
|
||
return
|
||
fake_head = Node(value + 1)
|
||
fake_head._next = self._head
|
||
prev, current = fake_head, self._head
|
||
while current:
|
||
if current.data != value:
|
||
prev._next = current
|
||
prev = prev._next
|
||
current = current._next
|
||
if prev._next:
|
||
prev._next = None
|
||
self._head = fake_head._next # in case head.data == value
|
||
|
||
def __repr__(self) -> str:
|
||
nums = []
|
||
current = self._head
|
||
while current:
|
||
nums.append(current.data)
|
||
current = current._next
|
||
if len(nums) > 0:
|
||
return "->".join(str(num) for num in nums)
|
||
else:
|
||
return ""
|
||
|
||
# 重写__iter__方法,方便for关键字调用打印值
|
||
def __iter__(self):
|
||
node = self._head
|
||
while node:
|
||
yield node.data
|
||
node = node._next
|
||
|
||
def print_all(self):
|
||
current = self._head
|
||
if current:
|
||
print(f"{current.data}", end="")
|
||
current = current._next
|
||
while current:
|
||
print(f"->{current.data}", end="")
|
||
current = current._next
|
||
print("\n", flush=True)
|
||
|
||
|
||
if __name__ == "__main__":
|
||
l = SinglyLinkedList()
|
||
for i in range(15):
|
||
l.insert_value_to_head(i)
|
||
node9 = l.find_by_value(9)
|
||
l.insert_value_before(node9, 20)
|
||
l.insert_value_before(node9, 16)
|
||
l.insert_value_before(node9, 16)
|
||
l.delete_by_value(16)
|
||
node11 = l.find_by_index(3)
|
||
l.delete_by_node(node11)
|
||
l.delete_by_node(l._head)
|
||
l.delete_by_value(13)
|
||
print(l)
|
||
for value in l:
|
||
print(value)
|