Module dsa.deque
Module containing deque classes.
Expand source code
""" Module containing deque classes. """
class Deque:
"""
A static deque implementation that supports appending and popping elements
from both ends, with a fixed capacity.
"""
def __init__(self, capacity: int=10):
"""
Initialize a deque with a fixed capacity.
Args:
capacity (int): The initial size of the deque (default is 10).
"""
self._array = [None] * capacity
self._left = -1
self._right = 0
self.count = 0
def append_left(self, element):
"""
Append an element to the left of the deque. Raises an exception when the deque is full.
Args:
element: The element to append.
Raises:
Exception: If the deque is full.
"""
if self.count >= self.capacity():
raise Exception("Deque Full")
if self._left < 0:
self._left = self.capacity() - 1
self._array[self._left] = element
self._left -= 1
self.count += 1
def append_right(self, element):
"""
Append an element to the right of the deque. Raises an exception when the deque is full.
Args:
element: The element to append.
Raises:
Exception: If the deque is full.
"""
if self.count >= self.capacity():
raise Exception("Deque Full")
if self._right > self.capacity() - 1:
self._right = 0
self._array[self._right] = element
self._right += 1
self.count += 1
def pop_left(self):
"""
Remove and return the element from the left of the deque. Raises an exception if the deque is empty.
Returns:
The leftmost element of the deque.
Raises:
Exception: If the deque is empty.
"""
if self.is_empty():
raise Exception("Empty Deque")
element = self._array[self._left + 1]
self._left += 1
if self._left + 1 >= len(self._array):
self._left = -1
self.count -= 1
return element
def pop_right(self):
"""
Pop an element from right the deque. Raise an exception if the deque is empty.
Returns:
The rightmost element of the deque.
Raises:
Exception: If the deque is empty.
"""
if self.is_empty():
raise Exception("Empty Deque")
element = self._array[self._right - 1]
self.count -= 1
self._right -= 1
if self._right < 0:
self._right = len(self._array) - 1
return element
def peek_left(self):
"""
Get the element at the left of the deque without removing it.
Raises an exception if the deque is empty.
Returns:
The leftmost element.
Raises:
Exception: If the deque is empty.
"""
if self.is_empty():
raise Exception("Empty deque")
return self._array[self._left + 1]
def peek_right(self):
"""
Get the element at the right of the deque without removing it.
Raises an exception if the deque is empty.
Returns:
The rightmost element.
Raises:
Exception: If the deque is empty.
"""
if self.is_empty():
raise Exception("Empty deque")
return self._array[self._right - 1]
def is_empty(self) -> bool:
"""
Return a Boolean on whether the deque is empty or not.
"""
return self.count == 0
@classmethod
def from_list(cls, alist: list):
"""
Create a deque from a given list. Raises an exception if list exceeds the deque's capacity.
Args:
alist: The list to initialize the deque with.
Returns:
a deque instance with elements from the list.
Raises:
Exception: If list exceeds the deque's capacity.
"""
dq = cls()
for e in alist:
dq.append_right(e)
return dq
def to_list(self):
"""
Convert the deque's contents into a list.
Returns:
A list containg the elements in the deque.
"""
arr = []
for i in range(self.count):
index = (i + self._left + 1) % len(self._array)
arr.append(self._array[index])
return arr
def capacity(self) -> int:
"""
Get the maximum capacity of the deque.
Returns:
The capacity of the deque.
"""
return len(self._array)
def __len__(self) -> int:
"""
Get the number of elements in the deque.
Returns:
The count of elements.
"""
return self.count
def __repr__(self):
"""
String representation of the deque for debugging purposes.
Returns:
A string displaying the contents and size of the deque.
"""
arr = []
for i in range(self.count):
index = (i + self._left + 1) % len(self._array)
arr.append(str(self._array[index]))
arrstr = ", ".join(arr)
return f"[{arrstr}] Count: {self.count} Capacity: {len(self._array)}" # {self.array}"
class DynamicDeque(Deque):
"""
A dynamic deque implementation that adjusts its capacity as needed.
"""
def grow(self):
"""
Helper method to double the capacity of the deque.
"""
new_array = [ None ] * self.capacity() * 2
# copy elements
for i in range(self.count):
index = (i + self._left + 1) % len(self._array)
new_array[i] = self._array[index]
self._array = new_array
self._left = -1
self._right = self.count
def shrink(self):
"""
Helper method to halve the capacity of the deque.
"""
if self.capacity() < 10:
return
new_capacity = self.capacity() // 2
new_array = [ None ] * new_capacity
# copy elements
for i in range(self.count):
index = (i + self._left + 1) % len(self._array)
new_array[i] = self._array[index]
self._array = new_array
self._left = -1
self._right = self.count
def check_capacity(self):
"""
Helper method to adjust the capacity of the deque based on its count:
if count >= capacity, grow the deque
if count <= 1/4 of capacity, shrink the deque
"""
if self.count >= self.capacity():
self.grow()
elif self.count * 4 <= self.capacity():
self.shrink()
def append_left(self, element):
"""
Append an element to the left, adjusting capacity if needed.
Args:
element: The element to append.
"""
self.check_capacity()
super().append_left(element)
def append_right(self, element):
"""
Append an element to the right, adjusting capacity if needed.
Args:
element: The element to append.
"""
self.check_capacity()
super().append_right(element)
def pop_left(self):
"""
Remove and return the element from the left, adjusting capacity if needed.
Returns:
The leftmost element.
"""
self.check_capacity()
return super().pop_left()
def pop_right(self):
"""
Remove and return the element from the right, adjusting capacity if needed.
Returns:
The rightmost element.
"""
self.check_capacity()
return super().pop_right()
Classes
class Deque (capacity: int = 10)
-
A static deque implementation that supports appending and popping elements from both ends, with a fixed capacity.
Initialize a deque with a fixed capacity.
Args
capacity
:int
- The initial size of the deque (default is 10).
Expand source code
class Deque: """ A static deque implementation that supports appending and popping elements from both ends, with a fixed capacity. """ def __init__(self, capacity: int=10): """ Initialize a deque with a fixed capacity. Args: capacity (int): The initial size of the deque (default is 10). """ self._array = [None] * capacity self._left = -1 self._right = 0 self.count = 0 def append_left(self, element): """ Append an element to the left of the deque. Raises an exception when the deque is full. Args: element: The element to append. Raises: Exception: If the deque is full. """ if self.count >= self.capacity(): raise Exception("Deque Full") if self._left < 0: self._left = self.capacity() - 1 self._array[self._left] = element self._left -= 1 self.count += 1 def append_right(self, element): """ Append an element to the right of the deque. Raises an exception when the deque is full. Args: element: The element to append. Raises: Exception: If the deque is full. """ if self.count >= self.capacity(): raise Exception("Deque Full") if self._right > self.capacity() - 1: self._right = 0 self._array[self._right] = element self._right += 1 self.count += 1 def pop_left(self): """ Remove and return the element from the left of the deque. Raises an exception if the deque is empty. Returns: The leftmost element of the deque. Raises: Exception: If the deque is empty. """ if self.is_empty(): raise Exception("Empty Deque") element = self._array[self._left + 1] self._left += 1 if self._left + 1 >= len(self._array): self._left = -1 self.count -= 1 return element def pop_right(self): """ Pop an element from right the deque. Raise an exception if the deque is empty. Returns: The rightmost element of the deque. Raises: Exception: If the deque is empty. """ if self.is_empty(): raise Exception("Empty Deque") element = self._array[self._right - 1] self.count -= 1 self._right -= 1 if self._right < 0: self._right = len(self._array) - 1 return element def peek_left(self): """ Get the element at the left of the deque without removing it. Raises an exception if the deque is empty. Returns: The leftmost element. Raises: Exception: If the deque is empty. """ if self.is_empty(): raise Exception("Empty deque") return self._array[self._left + 1] def peek_right(self): """ Get the element at the right of the deque without removing it. Raises an exception if the deque is empty. Returns: The rightmost element. Raises: Exception: If the deque is empty. """ if self.is_empty(): raise Exception("Empty deque") return self._array[self._right - 1] def is_empty(self) -> bool: """ Return a Boolean on whether the deque is empty or not. """ return self.count == 0 @classmethod def from_list(cls, alist: list): """ Create a deque from a given list. Raises an exception if list exceeds the deque's capacity. Args: alist: The list to initialize the deque with. Returns: a deque instance with elements from the list. Raises: Exception: If list exceeds the deque's capacity. """ dq = cls() for e in alist: dq.append_right(e) return dq def to_list(self): """ Convert the deque's contents into a list. Returns: A list containg the elements in the deque. """ arr = [] for i in range(self.count): index = (i + self._left + 1) % len(self._array) arr.append(self._array[index]) return arr def capacity(self) -> int: """ Get the maximum capacity of the deque. Returns: The capacity of the deque. """ return len(self._array) def __len__(self) -> int: """ Get the number of elements in the deque. Returns: The count of elements. """ return self.count def __repr__(self): """ String representation of the deque for debugging purposes. Returns: A string displaying the contents and size of the deque. """ arr = [] for i in range(self.count): index = (i + self._left + 1) % len(self._array) arr.append(str(self._array[index])) arrstr = ", ".join(arr) return f"[{arrstr}] Count: {self.count} Capacity: {len(self._array)}" # {self.array}"
Subclasses
Static methods
def from_list(alist: list)
-
Create a deque from a given list. Raises an exception if list exceeds the deque's capacity.
Args
alist
- The list to initialize the deque with.
Returns
a deque instance with elements from the list.
Raises
Exception
- If list exceeds the deque's capacity.
Expand source code
@classmethod def from_list(cls, alist: list): """ Create a deque from a given list. Raises an exception if list exceeds the deque's capacity. Args: alist: The list to initialize the deque with. Returns: a deque instance with elements from the list. Raises: Exception: If list exceeds the deque's capacity. """ dq = cls() for e in alist: dq.append_right(e) return dq
Methods
def append_left(self, element)
-
Append an element to the left of the deque. Raises an exception when the deque is full.
Args
element
- The element to append.
Raises
Exception
- If the deque is full.
Expand source code
def append_left(self, element): """ Append an element to the left of the deque. Raises an exception when the deque is full. Args: element: The element to append. Raises: Exception: If the deque is full. """ if self.count >= self.capacity(): raise Exception("Deque Full") if self._left < 0: self._left = self.capacity() - 1 self._array[self._left] = element self._left -= 1 self.count += 1
def append_right(self, element)
-
Append an element to the right of the deque. Raises an exception when the deque is full.
Args
element
- The element to append.
Raises
Exception
- If the deque is full.
Expand source code
def append_right(self, element): """ Append an element to the right of the deque. Raises an exception when the deque is full. Args: element: The element to append. Raises: Exception: If the deque is full. """ if self.count >= self.capacity(): raise Exception("Deque Full") if self._right > self.capacity() - 1: self._right = 0 self._array[self._right] = element self._right += 1 self.count += 1
def capacity(self) ‑> int
-
Get the maximum capacity of the deque.
Returns
The capacity of the deque.
Expand source code
def capacity(self) -> int: """ Get the maximum capacity of the deque. Returns: The capacity of the deque. """ return len(self._array)
def is_empty(self) ‑> bool
-
Return a Boolean on whether the deque is empty or not.
Expand source code
def is_empty(self) -> bool: """ Return a Boolean on whether the deque is empty or not. """ return self.count == 0
def peek_left(self)
-
Get the element at the left of the deque without removing it. Raises an exception if the deque is empty.
Returns
The leftmost element.
Raises
Exception
- If the deque is empty.
Expand source code
def peek_left(self): """ Get the element at the left of the deque without removing it. Raises an exception if the deque is empty. Returns: The leftmost element. Raises: Exception: If the deque is empty. """ if self.is_empty(): raise Exception("Empty deque") return self._array[self._left + 1]
def peek_right(self)
-
Get the element at the right of the deque without removing it. Raises an exception if the deque is empty.
Returns
The rightmost element.
Raises
Exception
- If the deque is empty.
Expand source code
def peek_right(self): """ Get the element at the right of the deque without removing it. Raises an exception if the deque is empty. Returns: The rightmost element. Raises: Exception: If the deque is empty. """ if self.is_empty(): raise Exception("Empty deque") return self._array[self._right - 1]
def pop_left(self)
-
Remove and return the element from the left of the deque. Raises an exception if the deque is empty.
Returns
The leftmost element of the deque.
Raises
Exception
- If the deque is empty.
Expand source code
def pop_left(self): """ Remove and return the element from the left of the deque. Raises an exception if the deque is empty. Returns: The leftmost element of the deque. Raises: Exception: If the deque is empty. """ if self.is_empty(): raise Exception("Empty Deque") element = self._array[self._left + 1] self._left += 1 if self._left + 1 >= len(self._array): self._left = -1 self.count -= 1 return element
def pop_right(self)
-
Pop an element from right the deque. Raise an exception if the deque is empty.
Returns
The rightmost element of the deque.
Raises
Exception
- If the deque is empty.
Expand source code
def pop_right(self): """ Pop an element from right the deque. Raise an exception if the deque is empty. Returns: The rightmost element of the deque. Raises: Exception: If the deque is empty. """ if self.is_empty(): raise Exception("Empty Deque") element = self._array[self._right - 1] self.count -= 1 self._right -= 1 if self._right < 0: self._right = len(self._array) - 1 return element
def to_list(self)
-
Convert the deque's contents into a list.
Returns
A list containg the elements in the deque.
Expand source code
def to_list(self): """ Convert the deque's contents into a list. Returns: A list containg the elements in the deque. """ arr = [] for i in range(self.count): index = (i + self._left + 1) % len(self._array) arr.append(self._array[index]) return arr
class DynamicDeque (capacity: int = 10)
-
A dynamic deque implementation that adjusts its capacity as needed.
Initialize a deque with a fixed capacity.
Args
capacity
:int
- The initial size of the deque (default is 10).
Expand source code
class DynamicDeque(Deque): """ A dynamic deque implementation that adjusts its capacity as needed. """ def grow(self): """ Helper method to double the capacity of the deque. """ new_array = [ None ] * self.capacity() * 2 # copy elements for i in range(self.count): index = (i + self._left + 1) % len(self._array) new_array[i] = self._array[index] self._array = new_array self._left = -1 self._right = self.count def shrink(self): """ Helper method to halve the capacity of the deque. """ if self.capacity() < 10: return new_capacity = self.capacity() // 2 new_array = [ None ] * new_capacity # copy elements for i in range(self.count): index = (i + self._left + 1) % len(self._array) new_array[i] = self._array[index] self._array = new_array self._left = -1 self._right = self.count def check_capacity(self): """ Helper method to adjust the capacity of the deque based on its count: if count >= capacity, grow the deque if count <= 1/4 of capacity, shrink the deque """ if self.count >= self.capacity(): self.grow() elif self.count * 4 <= self.capacity(): self.shrink() def append_left(self, element): """ Append an element to the left, adjusting capacity if needed. Args: element: The element to append. """ self.check_capacity() super().append_left(element) def append_right(self, element): """ Append an element to the right, adjusting capacity if needed. Args: element: The element to append. """ self.check_capacity() super().append_right(element) def pop_left(self): """ Remove and return the element from the left, adjusting capacity if needed. Returns: The leftmost element. """ self.check_capacity() return super().pop_left() def pop_right(self): """ Remove and return the element from the right, adjusting capacity if needed. Returns: The rightmost element. """ self.check_capacity() return super().pop_right()
Ancestors
Methods
def append_left(self, element)
-
Append an element to the left, adjusting capacity if needed.
Args
element
- The element to append.
Expand source code
def append_left(self, element): """ Append an element to the left, adjusting capacity if needed. Args: element: The element to append. """ self.check_capacity() super().append_left(element)
def append_right(self, element)
-
Append an element to the right, adjusting capacity if needed.
Args
element
- The element to append.
Expand source code
def append_right(self, element): """ Append an element to the right, adjusting capacity if needed. Args: element: The element to append. """ self.check_capacity() super().append_right(element)
def check_capacity(self)
-
Helper method to adjust the capacity of the deque based on its count: if count >= capacity, grow the deque if count <= 1/4 of capacity, shrink the deque
Expand source code
def check_capacity(self): """ Helper method to adjust the capacity of the deque based on its count: if count >= capacity, grow the deque if count <= 1/4 of capacity, shrink the deque """ if self.count >= self.capacity(): self.grow() elif self.count * 4 <= self.capacity(): self.shrink()
def grow(self)
-
Helper method to double the capacity of the deque.
Expand source code
def grow(self): """ Helper method to double the capacity of the deque. """ new_array = [ None ] * self.capacity() * 2 # copy elements for i in range(self.count): index = (i + self._left + 1) % len(self._array) new_array[i] = self._array[index] self._array = new_array self._left = -1 self._right = self.count
def pop_left(self)
-
Remove and return the element from the left, adjusting capacity if needed.
Returns
The leftmost element.
Expand source code
def pop_left(self): """ Remove and return the element from the left, adjusting capacity if needed. Returns: The leftmost element. """ self.check_capacity() return super().pop_left()
def pop_right(self)
-
Remove and return the element from the right, adjusting capacity if needed.
Returns
The rightmost element.
Expand source code
def pop_right(self): """ Remove and return the element from the right, adjusting capacity if needed. Returns: The rightmost element. """ self.check_capacity() return super().pop_right()
def shrink(self)
-
Helper method to halve the capacity of the deque.
Expand source code
def shrink(self): """ Helper method to halve the capacity of the deque. """ if self.capacity() < 10: return new_capacity = self.capacity() // 2 new_array = [ None ] * new_capacity # copy elements for i in range(self.count): index = (i + self._left + 1) % len(self._array) new_array[i] = self._array[index] self._array = new_array self._left = -1 self._right = self.count
Inherited members