forked from wangzheng0822/algo
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
implemented singly-linked list in Python
- Loading branch information
1 parent
c206df9
commit b86cd91
Showing
1 changed file
with
139 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,139 @@ | ||
""" | ||
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=None): | ||
self.data = data | ||
self._next = next | ||
|
||
|
||
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 = None | ||
|
||
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 "" | ||
|
||
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) |