that should cover linked lists (and their derivates Stacks and Queues)

This commit is contained in:
Stefan Harmuth 2022-01-14 11:23:00 +01:00
parent c2b36a0e73
commit dbd308dbf3

View File

@ -9,41 +9,6 @@ class Node:
prev: 'Node' = None prev: 'Node' = None
class Stack:
_tail: Node = None
size: int = 0
def push(self, obj: Any):
self._tail = Node(obj, self._tail)
self.size += 1
def pop(self) -> Any:
if self._tail is None:
raise ValueError('No more objects on stack')
res = self._tail.value
self._tail = self._tail.next
self.size -= 1
return res
def peek(self) -> Any:
if self._tail is None:
raise ValueError('No more objects on stack')
return self._tail.value
def __contains__(self, obj: Any) -> bool:
x = self._tail
while x.value != obj and x.next is not None:
x = x.next
return x.value == obj
class Queue:
pass
class LinkedList: class LinkedList:
_head: Union[Node, None] = None _head: Union[Node, None] = None
_tail: Union[Node, None] = None _tail: Union[Node, None] = None
@ -69,19 +34,16 @@ class LinkedList:
i_node.prev, i_node.next = node.prev, node i_node.prev, i_node.next = node.prev, node
node.prev = i_node node.prev = i_node
if node.prev is not None: if i_node.prev is not None:
node.prev.next = i_node i_node.prev.next = i_node
if index == 0: if index == 0:
self._head = i_node self._head = i_node
if index == self.size - 1:
self._tail = i_node
self.size += 1 self.size += 1
def _get_node(self, index: int) -> Node: def _get_node(self, index: int) -> Node:
if abs(index) >= self.size: if index >= self.size or index < -self.size:
raise IndexError("index out of bounds") raise IndexError("index out of bounds")
if index < 0: if index < 0:
@ -110,36 +72,22 @@ class LinkedList:
raise IndexError("pop from empty list") raise IndexError("pop from empty list")
if index is None: # pop from the tail if index is None: # pop from the tail
node = self._tail index = -1
if self.size > 1:
self._tail = self._tail.prev
self._tail.next = None
else:
self._head = None
self._tail = None
ret = node.value node = self._get_node(index)
elif index == 0: # pop from the head if node.prev is not None:
node = self._head node.prev.next = node.next
if self.size > 1:
self._head = self._head.next
self._head.prev = None
else:
self._head = None
self._tail = None
ret = node.value
else: else:
node = self._get_node(index) self._head = node.next
if node.prev is not None: if node.next is not None:
node.prev.next = node.next node.next.prev = node.prev
if node.next is not None: else:
node.next.prev = node.prev self._tail = node.prev
node.prev = None
node.next = None
ret = node.value
ret = node.value
del node
self.size -= 1 self.size -= 1
return ret return ret
def append(self, obj: Any): def append(self, obj: Any):
@ -154,14 +102,64 @@ class LinkedList:
def pop(self, index: int = None) -> Any: def pop(self, index: int = None) -> Any:
return self._pop(index) return self._pop(index)
def debug(self): def __contains__(self, obj: Any) -> bool:
print("head:", self._head) x = self._head
print("tail:", self._tail) while x.value != obj and x.next is not None:
if self.size > 0: x = x.next
x = 0
o = self._head return x.value == obj
print(x, o.value)
while o.next is not None: def __add__(self, other: 'LinkedList') -> 'LinkedList':
x += 1 self._tail.next = other._head
o = o.next other._head.prev = self._tail
print(x, o.value) self._tail = other._tail
self.size += other.size
return self
def __getitem__(self, index: int):
return self._get(index)
def __setitem__(self, index: int, obj: Any):
self._get_node(index).value = obj
def __len__(self):
return self.size
def __repr__(self):
x = self._head
if x is None:
v = ""
else:
v = str(x.value)
while x.next is not None:
x = x.next
v += ", " + str(x.value)
return "%s(%s)" % (self.__class__.__name__, v)
def __str__(self):
return self.__repr__()
class Stack(LinkedList):
def push(self, obj: Any):
self._append(obj)
def pop(self) -> Any:
return self._pop()
def peek(self) -> Any:
return self._tail.value
class Queue(LinkedList):
def enqueue(self, obj: Any):
self._append(obj)
def dequeue(self) -> Any:
return self._pop(0)
def peek(self) -> Any:
return self._head.value
push = enqueue
pop = dequeue