Skip to content

Instantly share code, notes, and snippets.

@tinytengu
Created May 4, 2021 09:16
Show Gist options
  • Save tinytengu/b053ab10ff8c02f11e860a51d0f75fdb to your computer and use it in GitHub Desktop.
Save tinytengu/b053ab10ff8c02f11e860a51d0f75fdb to your computer and use it in GitHub Desktop.
Python Linked List Implementation
class InvalidNodeIndex(Exception):
"""InvalidNodeIndex class"""
def __init__(self, index, node=None):
self.index = index
self.node = node
def __str__(self):
return "Invalid node index: %i" % (self.index)
class Node:
"""
Node class, represents linked list node
:param value: node value
:type value: any
:param next: next node element
:type next: Node
:return: node depth
:rtype: int
"""
def __init__(self, value=None, next=None):
self.value = value
self.next = next
@property
def depth(self):
"""
Get node depth
"""
depth = 0
current = self
while current.next is not None:
depth += 1
current = current.next
return depth
class LinkedList:
"""
LinkedList class, represents linked list type
:param elements: list elements
:type elements: list
"""
def __init__(self, elements=[]):
self._apply_defaults()
for element in elements:
self.add(element)
def __str__(self):
if self.first is None:
return self.__class__.__name__ + "[]"
elements = []
current = self.first
elements.append(current)
while current.next is not None:
current = current.next
elements.append(current)
return self.__class__.__name__ + "[{}]".format(', '.join(str(e.value) for e in elements))
def __len__(self):
if self.first is None:
return 0
return self.first.depth + 1
def _apply_defaults(self):
"""
Apply linked list default values
"""
self.first = None
self.last = None
@property
def is_empty(self):
"""
Check if linked list is empty
:return: empty result
:rtype: bool
"""
return self.first is None
def clear(self):
"""
Clear linked list nodes
"""
self._apply_defaults()
def add(self, element):
"""
Add element to linked list
:param element: element
:type element: any
"""
if self.first is None:
self.last = self.first = Node(element, None)
else:
self.last.next = self.last = Node(element, None)
def push(self, element):
"""
Add element at the beginning of linked list
:param element: element
:type element: any
"""
if self.first is None:
self.last = self.first = Node(element, None)
return
self.first = Node(element, self.first)
def remove(self, index):
"""
Remove element from linked list
:param index: element index
:type index: int
"""
if self.is_empty or index >= len(self):
raise InvalidNodeIndex(index)
if index == 0:
self.first = self.first.next
return
current = self.first
old = self.first
node_idx = 0
while current is not None:
if node_idx == index:
if current.next is None:
self.last = current
old.next = current.next
break
old = current
current = current.next
node_idx += 1
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment