143 lines
3.0 KiB
Python
143 lines
3.0 KiB
Python
class Node:
|
|
def __init__(self, payLoad, next=None):
|
|
self.payLoad = payLoad
|
|
self.next = next
|
|
|
|
def __str__(self):
|
|
return str(self.payLoad)
|
|
|
|
def __repr__(self):
|
|
return self.__str__()
|
|
|
|
class LinkedList:
|
|
def __init__(self, item):
|
|
self.next = self.next = self.__check_Node(item)
|
|
self.head = self.next
|
|
|
|
def __repr__(self):
|
|
return self.__str__()
|
|
|
|
def __add__(self, item):
|
|
'''allow += and + operates to work correctly'''
|
|
if item is self: return False
|
|
self.push( item )
|
|
|
|
return self
|
|
|
|
def __iter__(self):
|
|
'''allow the in operator to work'''
|
|
current = self.next
|
|
|
|
while isinstance(current, Node):
|
|
yield current
|
|
current = current.next
|
|
|
|
def __len__(self):
|
|
'''allow the len() function to be used'''
|
|
return self.find( None )['count']
|
|
|
|
def __str__(self):
|
|
'''allow print to work correctly'''
|
|
current = self.next
|
|
out = 'Head' + ' => '
|
|
|
|
for current in self:
|
|
# while current:
|
|
out += str(current.payLoad) + ' => '
|
|
current = current.next
|
|
|
|
return out + 'None'
|
|
|
|
def __check_Node(self, node):
|
|
'''internal method check if node is a node object'''
|
|
if isinstance(node, self.__class__):
|
|
return node.head
|
|
|
|
if not isinstance(node, Node):
|
|
return Node(node)
|
|
|
|
return node
|
|
|
|
def find(self, match):
|
|
''' Searches the list for a matching node. If found it will return the
|
|
current node, last node as Node objects and position as an int.
|
|
If nothing is found, it will return None, the last node as a Node
|
|
object, and the full length of the list as an int.
|
|
|
|
This function will **ONLY** return the first match.
|
|
|
|
setting match to None will find the end of the list and return the
|
|
last node as return['last']
|
|
|
|
This method does alot of the heavy lifting.
|
|
'''
|
|
|
|
current = self.next
|
|
last = None
|
|
count = 0
|
|
|
|
while current:
|
|
if current.payLoad == match:
|
|
return {'current': current, 'last': last, 'count': count}
|
|
|
|
last = current
|
|
current = current.next
|
|
count += 1
|
|
|
|
return {'current': current, 'last': last, 'count': count}
|
|
|
|
def insert(self, *items, after=False):
|
|
|
|
# figures out the position of the node
|
|
previous_node = self.find(after)['current'] if after != False else self
|
|
|
|
for item in items[:: -1]:
|
|
|
|
if isinstance(item, self.__class__):
|
|
item = item.next
|
|
|
|
item = self.__check_Node( item )
|
|
item.next = previous_node.next
|
|
previous_node.next = item
|
|
|
|
return self
|
|
|
|
def push(self, item):
|
|
last_node = self.find(None)['last']
|
|
node = self.__check_Node(item)
|
|
last_node.next = node;
|
|
|
|
|
|
def print_right(self):
|
|
|
|
def rec(current):
|
|
if not current: return 'None'
|
|
return rec( current.next ) + ' <= ' + current.payLoad
|
|
|
|
return rec( self.next ) + ' <= Head'
|
|
|
|
def delete(self, payLoad):
|
|
match = self.find( payLoad )
|
|
if match['current']:
|
|
match['last'].next = match['current'].next
|
|
return match['current'];
|
|
|
|
return None
|
|
|
|
if __name__ == '__main__':
|
|
''' Some testing stuff '''
|
|
l1 = LinkedList('b')
|
|
l1.insert('a')
|
|
l1.push('c')
|
|
|
|
print(l1)
|
|
|
|
l2 = LinkedList('1')
|
|
l2.push('2')
|
|
|
|
print(l2)
|
|
|
|
l1 +=l2
|
|
print(l1)
|
|
|