that should cover linked lists (and their derivates Stacks and Queues)
This commit is contained in:
parent
c2b36a0e73
commit
dbd308dbf3
146
tools/lists.py
146
tools/lists.py
@ -9,41 +9,6 @@ class Node:
|
||||
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:
|
||||
_head: Union[Node, None] = None
|
||||
_tail: Union[Node, None] = None
|
||||
@ -69,19 +34,16 @@ class LinkedList:
|
||||
|
||||
i_node.prev, i_node.next = node.prev, node
|
||||
node.prev = i_node
|
||||
if node.prev is not None:
|
||||
node.prev.next = i_node
|
||||
if i_node.prev is not None:
|
||||
i_node.prev.next = i_node
|
||||
|
||||
if index == 0:
|
||||
self._head = i_node
|
||||
|
||||
if index == self.size - 1:
|
||||
self._tail = i_node
|
||||
|
||||
self.size += 1
|
||||
|
||||
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")
|
||||
|
||||
if index < 0:
|
||||
@ -110,36 +72,22 @@ class LinkedList:
|
||||
raise IndexError("pop from empty list")
|
||||
|
||||
if index is None: # pop from the tail
|
||||
node = self._tail
|
||||
if self.size > 1:
|
||||
self._tail = self._tail.prev
|
||||
self._tail.next = None
|
||||
else:
|
||||
self._head = None
|
||||
self._tail = None
|
||||
index = -1
|
||||
|
||||
ret = node.value
|
||||
elif index == 0: # pop from the head
|
||||
node = self._head
|
||||
if self.size > 1:
|
||||
self._head = self._head.next
|
||||
self._head.prev = None
|
||||
else:
|
||||
self._head = None
|
||||
self._tail = None
|
||||
|
||||
ret = node.value
|
||||
else:
|
||||
node = self._get_node(index)
|
||||
if node.prev is not None:
|
||||
node.prev.next = node.next
|
||||
else:
|
||||
self._head = node.next
|
||||
if node.next is not None:
|
||||
node.next.prev = node.prev
|
||||
node.prev = None
|
||||
node.next = None
|
||||
ret = node.value
|
||||
else:
|
||||
self._tail = node.prev
|
||||
|
||||
ret = node.value
|
||||
del node
|
||||
self.size -= 1
|
||||
|
||||
return ret
|
||||
|
||||
def append(self, obj: Any):
|
||||
@ -154,14 +102,64 @@ class LinkedList:
|
||||
def pop(self, index: int = None) -> Any:
|
||||
return self._pop(index)
|
||||
|
||||
def debug(self):
|
||||
print("head:", self._head)
|
||||
print("tail:", self._tail)
|
||||
if self.size > 0:
|
||||
x = 0
|
||||
o = self._head
|
||||
print(x, o.value)
|
||||
while o.next is not None:
|
||||
x += 1
|
||||
o = o.next
|
||||
print(x, o.value)
|
||||
def __contains__(self, obj: Any) -> bool:
|
||||
x = self._head
|
||||
while x.value != obj and x.next is not None:
|
||||
x = x.next
|
||||
|
||||
return x.value == obj
|
||||
|
||||
def __add__(self, other: 'LinkedList') -> 'LinkedList':
|
||||
self._tail.next = other._head
|
||||
other._head.prev = self._tail
|
||||
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
|
||||
|
||||
Loading…
Reference in New Issue
Block a user