Skip to content

Commit

Permalink
implemented singly-linked list in Python
Browse files Browse the repository at this point in the history
  • Loading branch information
jerryderry committed Oct 4, 2018
1 parent c206df9 commit b86cd91
Showing 1 changed file with 139 additions and 0 deletions.
139 changes: 139 additions & 0 deletions python/06_linkedlist/singly_linked_list.py
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)

0 comments on commit b86cd91

Please sign in to comment.