def test_stack(self): my_stack = Stack() numbers = [1, 2, 3, 4, 5, 6, 7, 8] # Push all the numbers in the numbers list in to my_stack for number in numbers: my_stack.push(number) # The stack shouldn't be empty self.assertFalse(my_stack.is_empty()) # The element at the head of the stack should be 8 self.assertEqual(my_stack.peek(), 8) # Pop 6 elements out last_element = None for number in range(0, 6): last_element = my_stack.pop() # The last element popped out should be 3 self.assertEqual(last_element.getData(), 3) # The element at the head of the stack should be 2 self.assertEqual(my_stack.peek(), 2) # Empty the stack for number in range(0, my_stack.size()): my_stack.pop() # The stack should now be empty self.assertTrue(my_stack.is_empty())
def sort_stack(origin_stack): auxiliary = Stack() end_stack = Stack() end_stack.push(origin_stack.pop().getData()) while origin_stack.is_empty() is False: # Store the data from the top node in origin_stack. temp_node_data = origin_stack.peek() # When temp_node_data no longer matches the data of the top node in origin_stack, then exit # and begin to evaluate the next node while origin_stack.peek() == temp_node_data: # If end_stack is empty, simply push in to it the top node from origin_stack if end_stack.is_empty(): end_stack.push(origin_stack.pop().getData()) break # If the top node in origin_stack is greater than the top_node in end_stack, push it over. # We are storing the data in descending order so that later we can easily transfer the nodes # back over to origin_stack in ascending order. elif origin_stack.peek() >= end_stack.peek(): end_stack.push(origin_stack.pop().getData()) break else: # Move the top node from end_stack out of the way by pushing it in to auxiliary so that # we can loop again and compare with the next node in auxiliary auxiliary.push(end_stack.pop().getData()) # Now push all nodes from auxiliary back in to end_stack while auxiliary.is_empty() is False: end_stack.push(auxiliary.pop().getData()) # print(end_stack.print_nodes()) # Finally, push all nodes from end_stack in to origin_stack in ascending order while end_stack.is_empty() is False: origin_stack.push(end_stack.pop().getData())
class StackFindMin(Stack): def __init__(self): # Bring in the super class's variables super(StackFindMin, self).__init__() # Use a regular stack to keep track of the history of minimal elements self._min_value = Stack() self._temp_stack = Stack() def push(self, item): # Call the parent class's push method super().push(item) # Continually compare item to the value at the top of min_value and append item # once the new element to the min_value stack if it is found to be smaller than what # is current at the top. self.set_min(item) def pop(self): # Call the parent class's pop method popped = super().pop() # Remove the node item value from the min_value stack if it happens to match # the minimum value currently residing at the top of the min_value stack. if popped.getData() == self._min_value.peek(): self._min_value.pop() return popped # Getter for the current minimum value def get_min(self): return self._min_value.peek() # Setter for the current minimum value def set_min(self, data): if not self.get_min(): self._min_value.push(data) else: while self.get_min() is not None and data > self.get_min(): self._temp_stack.push(self._min_value.pop().getData()) self._min_value.push(data) while self._temp_stack.peek() is not None: self._min_value.push(self._temp_stack.pop().getData())
class MyQueue: def __init__(self): self.main = Stack() self.temp = Stack() def put(self, data): while not self.main.is_empty(): self.temp.push(self.main.pop().getData()) self.main.push(data) while not self.temp.is_empty(): self.main.push(self.temp.pop().getData()) def get(self): return self.main.pop() def size(self): return self.main.size() def is_empty(self): return self.main.is_empty()
def dequeue_specific(self, type): # Initialise a temporary stack to hold the animals that are dequeued whilst searching for the specific animal # type temp = Stack() # Continually dequeue animals and push them in to the aforementioned Stack until the intended type of animal # is encountered while self.inspect_tail()[0] != type: temp.push(self.dequeue_any()) dequeued = self.dequeue_any() # Now pop all the animals from temp and enqueue back in to the Shelter while temp.size() > 0: new_animal = temp.pop().getData() self.enqueue(new_animal.get_data()[0], new_animal.get_data()[1]) self.size -= 1 return dequeued
def test_sort_stack(self): myStack = Stack() unsorted_numbers = [5, 5, 1, 3, 3, 2, 66, 4, 8, 3, 9, 10] for unsorted_num in unsorted_numbers: myStack.push(unsorted_num) sort_stack(myStack) # Let's test in sequence that all nodes are stored in ascending order self.assertEqual(myStack.pop().getData(), 1) self.assertEqual(myStack.pop().getData(), 2) self.assertEqual(myStack.pop().getData(), 3) self.assertEqual(myStack.pop().getData(), 3) self.assertEqual(myStack.pop().getData(), 3) self.assertEqual(myStack.pop().getData(), 4) self.assertEqual(myStack.pop().getData(), 5) self.assertEqual(myStack.pop().getData(), 5) self.assertEqual(myStack.pop().getData(), 8) self.assertEqual(myStack.pop().getData(), 9) self.assertEqual(myStack.pop().getData(), 10) self.assertEqual(myStack.pop().getData(), 66)
def pop_at(self, index): current_stack = self.stack_set.head temp = Stack() # Determine which stack the node resides in sub_stack = index // self.max_size # print("Sub-stack:", sub_stack) # If the index doesn't reside in the first stack (and hence there are more than one stack in # the set), then move to the specific stack. Also, remove the number of positions that must # be iterated through by deducting the positions from earlier stacks. if sub_stack > 0: counter = 0 for stack in range(0, sub_stack): current_stack = current_stack.getNext() counter += 1 # print("Shuffled to next stack") # current_node = current_stack.getData().top # while current_node is not None: # print(current_node.getData()) # current_node = current_node.getNext() # Now that we are operating on a specific stack only, get the index of the node item # with respect to where it sits in this stack. # particular_stack_index = index - self.max_size - current_stack.getData().stack_size particular_stack_index = index - self.max_size * counter # print(particular_stack_index) else: particular_stack_index = index # Also calculate and capture the number of nodes ahead of the particular index. # Note that we deduct a further 1 due to indexes starting at 0. num_nodes_ahead = current_stack.getData().size( ) - particular_stack_index - 1 # <- This doesn't make sense # Pop all the items ahead of the index and push them in to a temporary stack for indice in range(0, num_nodes_ahead): temp.push(current_stack.getData().pop().getData()) # Pop the top node out of the current stack which is the node item at 'index' popped_node = current_stack.getData().pop() self.items_count -= 1 # popped_node = super().pop() # Store a reference to the current_stack as we will need to come back to it to push the nodes back in from temp. placeholder = current_stack # Shuffle all node items up the set by one to fill the gap left by popping earlier. # The point of doing this is to maintaian the order of all node items in the Set while current_stack.getNext() is not None: current_stack.getData().push( current_stack.getNext().getData().pop().getData()) current_stack = current_stack.getNext() current_stack = placeholder # Push everything back in to the current stack from temp while temp.is_empty() is False: current_stack.getData().push(temp.pop().getData()) while current_stack.getNext() is not None: current_stack = current_stack.getNext() if self.tail_stack.is_empty(): self.stack_set.remove(self.tail_stack) current = self.stack_set.head while current.getNext() is not None: current = current.getNext() self.tail_stack = current self.stack_count -= 1 return popped_node