class LinkedQueue(object): def __init__(self, iterable=None): """Initialize this queue and enqueue the given items, if any.""" # Initialize a new linked list to store the items self.list = DoublyLinkedList() self.size = 0 if iterable is not None: for item in iterable: self.enqueue(item) def __repr__(self): """Return a string representation of this queue.""" return 'Queue({} items, front={})'.format(self.length(), self.front()) def is_empty(self): """Return True if this queue is empty, or False otherwise.""" # TODO: Check if empty return self.list.is_empty() def length(self): """Return the number of items in this queue.""" # TODO: Count number of items return self.size def enqueue(self, item): """Insert the given item at the back of this queue. Running Time and why O(1) every case, because we keep track of the tail at all times, and enqueue appends at the tail""" # TODO: Insert given item self.list.append(item) # set tail to the Node(item), constant time self.size += 1 def front(self): """Return the item at the front of this queue without removing it, or None if this queue is empty.""" # TODO: Return front item, if any if self.is_empty(): return None return self.list.head.data def dequeue(self): """Remove and return the item at the front of this queue, or raise ValueError if this queue is empty. Running Time and why O(1), because we keep track of the head at all times and dequeue removes at the head""" # TODO: Remove and return front item, if any if self.is_empty(): raise ValueError("Head is empty, can't dequeue") head = self.front() self.list.head = self.list.head.next self.size -= 1 return head
class LinkedDeque(object): def __init__(self, iterable=None): self.list = DoublyLinkedList() if iterable is not None: for item in iterable: self.push_back(item) def __repr__(self): """Return a string representation of this deque.""" return 'Deque({} items, front={}, back={})'.format( self.length(), self.front(), self.back()) def is_empty(self): """Return True if this deque is empty, or False otherwise.""" return self.list.is_empty() def length(self): """Return the number of items in this deque.""" return self.list.size def push_front(self, item): """Insert the given item at the front of this deque. Running time: O(1) - add item front of the DoublyLinkedList""" self.list.prepend(item) def push_back(self, item): """Insert the given item at the back of this deque. Running time: O(1) - add item back of the DoublyLinkedList""" self.list.append(item) def front(self): """Return the item at the front of this deque without removing it, or None if this deque is empty.""" if self.is_empty(): return None else: return self.list.head.data def back(self): """Return the item at the back of this deque without removing it, or None if this deque is empty.""" if self.is_empty(): return None else: return self.list.tail.data def pop_front(self): """remove and return the item at the front of the deque. Running time: O(1) - delete item front of the DoublyLinkedList""" if self.is_empty(): raise ValueError('This deque is empty.') else: data = self.front() self.list.head = self.list.head.next if self.list.head is None: self.list.tail = None else: self.list.head.previous = None self.list.size -= 1 return data def pop_back(self): """remove and return the item at the back of the deque. Running time: O(1) - delete item back of the DoublyLinkedList""" if self.is_empty(): raise ValueError('This deque is empty.') else: data = self.back() self.list.tail = self.list.tail.previous if self.list.tail is None: self.list.head = None else: self.list.tail.next = None self.list.size -= 1 return data