algo/python/06_linkedlist/singly_linked_list.py
scyes 01a1083f82
Update singly_linked_list.py
current._next = node._next in delete_by_node
2019-02-26 17:01:12 +08:00

148 lines
4.1 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"""
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)