Example #1
0
    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())
Example #2
0
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())
Example #3
0
    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
Example #4
0
    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)
Example #5
0
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())
Example #6
0
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()
Example #7
0
            # 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())
    # print(origin_stack.print_nodes())


if __name__ == '__main__':
    myStack = Stack()
    myStack.push(5)
    myStack.push(5)
    myStack.push(1)
    myStack.push(3)
    myStack.push(3)
    myStack.push(2)
    myStack.push(4)
    sort_stack(myStack)
    print(myStack.print_nodes())
Example #8
0
    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