def test_prepend(self): dll = DoublyLinkedList() dll.prepend('M') assert dll.head.data == 'M' assert dll.tail.data == 'M' dll.prepend('E') assert dll.head.data == 'E' assert dll.tail.data == 'M'
class Deque: def __init__(self, items=None): """ initializes a Deque with items if any are given. If items are given they are populated into Deque with push_front method (loading in front by default) """ # initialize linked list for our deque to use self.list = DoublyLinkedList() # build are deque if items is not None: for item in items: self.push_front(item) def push_front(item): """ Takes in given item and prepends it to the front of the deque """ # use linked list prepend method self.list.prepend(item) def push_back(item): """ Takes an item as parameter and appends it to the back of the deque """ # uses linked list append method self.list.append(item) def pop_front(): """ Removes the item at front of deque and returns it """ # grab item to be popped/returned popped_item = self.list.head # remove from left side of list using linkedlist delete method # note: this is still constant b/c popped_item is first item in linkedlist self.list.delete(popped_item) return popped_item # returning item that was just deleted def pop_back(): """ Removes the item at the end of deque and returns its value """ # grab item to be removed (tail of linked list) popped_item = self.list.tail # remove item from right side # currently O(n) self.list.delete(popped_item) return popped_item # return value of deleted item
def test_items(self): ll = DoublyLinkedList() assert ll.items() == [] ll.append('B') assert ll.items() == ['B'] ll.prepend('A') assert ll.items() == ['A', 'B'] ll.append('C') assert ll.items() == ['A', 'B', 'C']
class LinkedStack(object): def __init__(self, iterable=None): """Initialize this stack and push 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.push(item) def __repr__(self): """Return a string representation of this stack.""" return 'Stack({} items, top={})'.format(self.length(), self.peek()) def is_empty(self): """Return True if this stack is empty, or False otherwise.""" # TODO: Check if empty return self.peek() is None def length(self): """Return the number of items in this stack.""" # TODO: Count number of items return self.size def push(self, item): """Insert the given item on the top of this stack. O(1), we append an item to the tail, we always keep track of the tail""" # TODO: Push given item self.list.prepend(item) self.size += 1 def peek(self): """Return the item on the top of this stack without removing it, or None if this stack is empty.""" # TODO: Return top item, if any item = self.list.head if item is not None: return item.data return item def pop(self): """Remove and return the item on the top of this stack, or raise ValueError if this stack is empty. O(1), we remove an item from the tail, we always keep track of the tail and I also used a doubly linked list so we have the previous node pointer which helps with deleting the last item in the list without traversing it""" # TODO: Remove and return top item, if any if self.is_empty(): raise ValueError item = self.peek() self.list.head = self.list.head.next self.size -= 1 return item
def test_length_after_append_and_prepend(self): dll = DoublyLinkedList() assert dll.length() == 0 # Append and prepend should increase length dll.append('C') assert dll.length() == 1 dll.prepend('B') assert dll.length() == 2 dll.append('D') assert dll.length() == 3 dll.prepend('A') assert dll.length() == 4
def test_size(self): ll = DoublyLinkedList() assert ll.size == 0 # append and prepend operations increment size ll.append('B') assert ll.size == 1 ll.prepend('A') assert ll.size == 2 ll.append('C') assert ll.size == 3 # delete operations decrement size ll.delete('B') assert ll.size == 2 ll.delete('C') assert ll.size == 1 ll.delete('A') assert ll.size == 0
def test_length(self): ll = DoublyLinkedList() assert ll.length() == 0 # append and prepend operations increase length ll.append('B') assert ll.length() == 1 ll.prepend('A') assert ll.length() == 2 ll.append('C') assert ll.length() == 3 # delete operations decrease length ll.delete('B') assert ll.length() == 2 ll.delete('C') assert ll.length() == 1 ll.delete('A') assert ll.length() == 0
def test_length_after_prepend(self): dll = DoublyLinkedList() assert dll.length() == 0 # Prepend should increase length dll.prepend('C') assert dll.length() == 1 dll.prepend('B') assert dll.length() == 2 dll.prepend('A') assert dll.length() == 3
def test_items_after_prepend(self): dll = DoublyLinkedList() assert dll.items() == [] # Prepend should add new item to head of list dll.prepend('C') assert dll.items() == ['C'] dll.prepend('B') assert dll.items() == ['B', 'C'] dll.prepend('A') assert dll.items() == ['A', 'B', 'C']
def test_prepend(self): ll = DoublyLinkedList() ll.prepend('C') assert ll.head.data == 'C' assert ll.tail.data == 'C' ll.prepend('B') assert ll.head.data == 'B' assert ll.tail.data == 'C' ll.prepend('A') assert ll.head.data == 'A' assert ll.tail.data == 'C'
def test_prepend(self): dll = DoublyLinkedList() # Prepend should always update head node dll.prepend('C') assert dll.head.data == 'C' # New head assert dll.tail.data == 'C' # New head dll.prepend('B') assert dll.head.data == 'B' # New head assert dll.tail.data == 'C' # Unchanged dll.prepend('A') assert dll.head.data == 'A' # New head assert dll.tail.data == 'C' # Unchanged
def test_prepend(self): ll = DoublyLinkedList() ll.prepend('C') assert ll.head.data == 'C' # new head assert ll.tail.data == 'C' # new head assert ll.size == 1 ll.prepend('B') assert ll.head.data == 'B' # new head assert ll.tail.data == 'C' # unchanged assert ll.size == 2 ll.prepend('A') assert ll.head.data == 'A' # new head assert ll.tail.data == 'C' # unchanged assert ll.size == 3
def test_prepend(self): dll = DoublyLinkedList() dll.prepend('C') assert dll.head.data == 'C' assert dll.tail.data == 'C' assert dll.size == 1 dll.prepend('B') assert dll.head.data == 'B' assert dll.tail.data == 'C' assert dll.size == 2 dll.prepend('A') assert dll.head.data == 'A' assert dll.tail.data == 'C' assert dll.size == 3
class Deque(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() if iterable is not None: for item in iterable: self.push_back(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.""" return self.list.head is None and self.list.tail is None def length(self): """Return the number of items in this queue.""" return self.list.size def push_front(self, item): """Insert the given item at the front of this queue. Running time: O(1)""" self.list.prepend(item) def push_back(self, item): """Insert the given item at the back of this queue. Running time: O(1) – adding a new node with a linked list takes O(1) time""" self.list.append(item) def front(self): """Return the item at the front of this queue without removing it, or None if this queue is empty.""" if self.is_empty(): return None return self.list.head.data def back(self): """Return the item at the back of this queue without removing it, or None if this queue is empty.""" if self.is_empty(): return None return self.list.tail.data def pop_front(self): """Remove and return the item at the front of this queue, or raise ValueError if this queue is empty. Running time: O(1) – removing an item from the front of a linked list takes O(1)""" if self.is_empty(): raise ValueError('Queue us empty') data = self.list.head.data self.list.head = self.list.head.next self.list.size -= 1 if self.list.size == 0: self.list.tail = None self.list.head = None return data def pop_back(self): """Remove and return the item at the back of this queue, or raise ValueError if this queue is empty. Running time: O(1)""" if self.is_empty(): raise ValueError('Queue is empty') data = self.list.tail.data self.list.tail = self.list.tail.prev self.list.size -= 1 if self.list.size == 0: self.list.head = None self.list.tail = None return data
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