Linked Lists
September 17, 2020"""A singly linked list implementation.
Typical usage example:
l = SinglyLinkedList()
l.insertBeginning(1)
# [1]
l.insertAfter(l.head(), 2)
# [1,2]
l.insertAfter(l.head().next(), 3)
# [1,2,3]
l.removeAfter(l.head())
# [1,3]
l.removeBeginning()
# [3]
"""
from __future__ import annotations
import unittest
class Test(unittest.TestCase):
def setUp(self):
self.l = SinglyLinkedList()
def tearDown(self):
self.l = None
def test_simple(self):
self.assertEqual(str(self.l), '[]')
self.l.insertBeginning(1)
self.assertEqual(str(self.l), '[1]')
self.l.insertBeginning(2)
self.assertEqual(str(self.l), '[2,1]')
n = self.l.head().next()
self.l.insertAfter(n, 0)
self.assertEqual(str(self.l), '[2,1,0]')
n = self.l.head()
self.l.removeAfter(n)
self.assertEqual(str(self.l), '[2,0]')
self.l.removeBeginning()
self.assertEqual(str(self.l), '[0]')
self.l.removeAfter(self.l.head())
self.assertEqual(str(self.l), '[0]')
self.l.removeBeginning()
self.assertEqual(str(self.l), '[]')
class Node(object):
"""A node for a singly linked list.
Attributes:
v: the value stored at this node.
n: a pointer to the next node in the linked list.
"""
__slots__ = ['v', 'n']
def __init__(self, v, n: Node=None):
self.v = v
self.n = n
def __str__(self):
return str(self.v)
def next(self) -> Node:
"""Returns the Node after this Node.
Args: None.
Returns:
Node - the Node after this one.
"""
return self.n
class SinglyLinkedList(object):
"""A singly linked list.
Attributes:
h: the first node in this linked list.
"""
def __init__(self):
self.h = None
def __str__(self):
ns = []
curr = self.h
while curr:
ns.append(str(curr))
curr = curr.n
return f"[{','.join(ns)}]"
def head(self):
"""Returns the first Node in this linked list.
Args: None.
Returns:
Node - the first Node.
"""
return self.h
def insertAfter(self, n: Node, value):
"""Inserts the input value after the input Node.
Args:
n: the Node after which to insert the new <value>.
value: any value.
Return: None.
"""
n.n = Node(value, n.n)
def removeAfter(self, n: Node):
"""Removes the next Node after the input Node.
Args:
n: the Node after which to remove.
Return: None.
"""
if not n.n:
return
n.n = n.n.n
def insertBeginning(self, value):
"""Inserts the input value at the head of the linked list.
Args:
value: any value.
Return: None.
"""
self.h = Node(value, self.h)
def removeBeginning(self):
"""Removes the Node at the head of the linked list.
Args: None.
Return: None.
"""
if not self.h:
return
self.h = self.h.n