Source code for hal.data.linked_list
#!/usr/bin/env python
# coding: utf-8
"""Linked list implementation"""
[docs]class Node:
"""Node of a linked list"""
def __init__(self, val, next_node=None):
"""
:param val: Value of node
:param next_node: Next node
"""
self.val = val
self.next_node = next_node # the pointer initially points to nothing
[docs]class LinkedList:
"""Models a linked list"""
def __init__(self, lst):
"""
:param lst: List of elements
"""
self.head = LinkedList.from_list(lst)
[docs] def get_head(self):
"""Gets head
:return: Head of linked list
"""
return self.head
[docs] def get(self, position):
"""Gets value at index
:param position: index
:return: value at position
"""
counter = 0
current_node = self.head
while current_node is not None and counter <= position:
if counter == position:
return current_node.val
current_node = current_node.next_node
counter += 1
return None
[docs] def get_tail(self):
"""Gets tail
:return: Tail of linked list
"""
node = self.head
last_node = self.head
while node is not None:
last_node = node
node = node.next_node
return last_node
[docs] def length(self):
"""Gets length
:return: How many items in linked list of linked list
"""
item = self.head
counter = 0
while item is not None:
counter += 1
item = item.next_node
return counter
[docs] def insert_last(self, val):
"""Appends to list
:param val: Object to insert
:return: bool: Appends element to last
"""
return self.insert(val, self.length())
[docs] def insert_first(self, val):
"""Insert in head
:param val: Object to insert
:return: True iff insertion completed successfully
"""
self.head = Node(val, next_node=self.head)
return True
[docs] def insert(self, val, position=0):
"""Insert in position
:param val: Object to insert
:param position: Index of insertion
:return: bool: True iff insertion completed successfully
"""
if position <= 0: # at beginning
return self.insert_first(val)
counter = 0
last_node = self.head
current_node = self.head
while current_node is not None and counter <= position:
if counter == position:
last_node.next_node = Node(val, current_node)
return True
last_node = current_node
current_node = current_node.next_node
counter += 1
if current_node is None: # append to last element
last_node.next_node = Node(val, None)
return True
[docs] def remove_first(self):
"""Removes first
:return: True iff head has been removed
"""
if self.head is None:
return False
self.head = self.head.next_node
return True
[docs] def remove_last(self):
"""Removes last
:return: True iff last element has been removed
"""
if self.length() <= 1:
self.head = None
return True
node = self.head
while node is not None:
is_last_but_one = node.next_node is not None and \
node.next_node.next_node is None
print(node.val, is_last_but_one)
if is_last_but_one: # this is the last
node.next_node = None # get to last but one element
return True
node = node.next_node
return False
[docs] def remove(self, position):
"""Removes at index
:param position: Index of removal
:return: bool: True iff removal completed successfully
"""
if position <= 0: # at beginning
return self.remove_first()
if position >= self.length() - 1: # at end
return self.remove_last()
counter = 0
last_node = self.head
current_node = self.head
while current_node is not None and counter <= position:
if counter == position:
last_node.next_node = current_node.next_node # remove current
return True
last_node = current_node
current_node = current_node.next_node
counter += 1
return False
[docs] def to_lst(self):
"""Cycle all items and puts them in a list
:return: list representation
"""
out = []
node = self.head
while node is not None:
out.append(node.val)
node = node.next_node
return out
[docs] def execute(self, func, *args, **kwargs):
"""Executes function on each item
:param func: Function to execute on each item
:param args: args of function
:param kwargs: extra args of function
:return: list: Results of calling the function on each item
"""
return [
func(item, *args, **kwargs) for item in self.to_lst()
]
def __str__(self):
lst = self.to_lst()
lst = [
str(node) for node in lst
]
return " -> ".join(lst)
[docs] @staticmethod
def from_list(lst):
"""Parses list
:param lst: list of elements
:return: LinkedList: Nodes from list
"""
if not lst:
return None
head = Node(lst[0], None)
if len(lst) == 1:
return head
head.next_node = LinkedList.from_list(lst[1:])
return head