def reverse(nums): #declare your stack Stack = LinkedStack() #init the stack #declare a variable to get track of the reversed number reversed = [] #add each number in nums to the stack for num in nums: # Loop through the whole list O(n) if num == '-': reversed.append(num) #adds sign to list O(1) if num.isdigit(): Stack.push(num) #adds num to stack O(1) #traverse through the stack while Stack.length() > 0: # Loops through the whole stack #add the head of the stack then delete the head reversed.append(Stack.peek()) # adds number back to list O(1) Stack.pop() # deletes current stack to move to the next one O(1) if reversed[0] == '-': if reversed[1] == '0': reversed.pop(1) #removes a digit O(1) if reversed[0] == '0': reversed.pop(0) #removes a digit O(1) return "".join(reversed)
def _traverse_post_order_iterative(self, node, visit): """Traverse this binary tree with iterative post-order traversal (DFS). Start at the given node and visit each node with the given function. Running time: O(n) since we visit every node Memory usage: O(h) where h is the height of the tree""" # NOT WORKING # leftStack = LinkedStack() # rightStack = LinkedStack() # theRoot = node # stays the same until end # curr = node # will update this variable in the while loop # # visit all the left nodes # leftStack.push(theRoot.left) # while not leftStack.is_empty(): # toPop = leftStack.pop() # if toPop == None: # continue # visit(toPop.data) # leftStack.push(toPop.right) # leftStack.push(toPop.left) # print(leftStack.list) # # visit all the right nodes # rightStack.push(theRoot.right) # while not rightStack.is_empty(): # toPop = rightStack.pop() # if toPop == None: # continue # visit(toPop.data) # rightStack.push(toPop.right) # rightStack.push(toPop.left) # # before returning, we add the mid node (self.root) # visit(theRoot.data) # WORKING # -create 2 stacks where the second stack will be what we return starting from the peek to the end # -start the first stack with the root node # -loop through first stack while isn't empty # - pop from the first stack then add it to our second stack # - push left of the popped item # - push right of the popped item # -after our second stack has all the nodes, we can append to the list as we call pop() method startStack = LinkedStack() endStack = LinkedStack() startStack.push(node) while not startStack.is_empty(): toPop = startStack.pop() if toPop == None: continue endStack.push(toPop) startStack.push(toPop.left) startStack.push(toPop.right) while not endStack.is_empty(): visit(endStack.pop().data)
def test_pop(self): s = Stack(['A', 'B', 'C']) assert s.pop() == 'C' assert s.length() == 2 assert s.pop() == 'B' assert s.length() == 1 assert s.pop() == 'A' assert s.length() == 0 assert s.is_empty() is True with self.assertRaises(ValueError): s.pop()
def test_peek(self): s = Stack() assert s.peek() is None s.push('A') assert s.peek() == 'A' s.push('B') assert s.peek() == 'B' s.pop() assert s.peek() == 'A' s.pop() assert s.peek() is None
def test_length(self): s = Stack() assert s.length() == 0 s.push('A') assert s.length() == 1 s.push('B') assert s.length() == 2 s.pop() assert s.length() == 1 s.pop() assert s.length() == 0
def _traverse_in_order_iterative(self, node, visit): """ Traverse this binary tree with iterative in-order traversal (DFS). Start at the given node and visit each node with the given function. TODO: Running time: O(n) we visit every node in the tree TODO: Memory usage: O(n) because we are creating a stack """ # stack for holding horizon stack = LinkedStack() # tells when we are done traversing done = False # set node as start node to start current = node # traverse nodes while stack is not empty while not done: # traverse down left side of tree # appending nodes to stack if current is not None: stack.push(current) current = current.left # if node is none time to go grab # from stack else: # if stack is not empty pop and grab # top item in stack if not stack.is_empty(): current = stack.pop() # visit the node visit(current.data) # grab the right node (None is fine) current = current.right else: # All done! done = True
def _traverse_pre_order_iterative(self, node, visit): """Traverse this binary tree with iterative pre-order traversal (DFS). Start at the given node and visit each node with the given function. TODO: Running time: O(n) we visit every node in the tree TODO: Memory usage: O(n) because we are creating a stack """ # stack to use to store nodes in order stack = LinkedStack() # set current to the starting node current = node # load starting node into stack stack.push(current) # traverse until stack is empty while not stack.is_empty(): # pop and visit top node in stack current = stack.pop() visit(current.data) # NOTE: right is first because we are using stack # so right child will be under left child # if right child is present add to stack if current.right is not None: stack.push(current.right) # if left child is present add to stack if current.left is not None: stack.push(current.left)
def reverse(num): str_num = str(num) stack = LinkedStack(list(str_num)) reversed_num = "" while not stack.is_empty(): reversed_num += stack.pop() return int(reversed_num)
def _traverse_in_order_iterative(self, node, visit): """Traverse this binary tree with iterative in-order traversal (DFS). Start at the given node and visit each node with the given function. Running time: O(n) (n is # of nodes) Worst case since we are visiting every node. Memory usage: O(n) worst case if unbalanced - O(log n) if balanced since we will push n nodes in the recursive stack""" # Variables and pointers to keep track of nodes and status as we traverse curr_node = node stack = LinkedStack() done = False while not done: # Traverse until the leaf on the far right if curr_node is not done: stack.push(curr_node ) # Keep track of this current node for future use curr_node = curr_node.left # Go to the left subtree else: if not stack.is_empty(): curr_node = stack.pop( ) # grab the parent node that was pushed visit(curr_node) # visit its data curr_node = curr_node.right # go to the right tree else: done = True # The entire tree has been traversed in order
def _traverse_pre_order_iterative(self, node, visit): """Traverse this binary tree with iterative pre-order traversal (DFS). Start at the given node and visit each node with the given function. Running time: O(n) since we visit every node Memory usage: O(h) where h is the height of the tree""" # -create an empty stack and push the root node in there # -loop through while the stack isn't empty # -pop() on the stack # -push() the right node of the node we just popped off the stack # -pop() and left node of the node we just popped off the stack stack = LinkedStack() stack.push( node ) # since we're starting in the middle, we start the stack off with self.root while not stack.is_empty(): toPop = stack.pop() if toPop == None: continue # skip this one visit(toPop.data) # add in the data stack.push( toPop.right ) # add the right before the left since this is a stack, stack.push( toPop.left ) # the next time we look in the stack, the left will be seen before the right!!
def _traverse_in_order_iterative(self, node, visit): """Traverse this binary tree with iterative in-order traversal (DFS). Start at the given node and visit each node with the given function. Running time: O(n) since we visit every node Memory usage: O(logn) for the depth of the tree""" # -create an empty stack # -curr variable which starts off with the self.root (will be updated in a while loop!!) # -go in a while loop while true (will be false when the stack is empty) # -call push() on curr while there's a value # -update the curr to become the curr's left # -once we hit a None value: # - we'd want to pop() off the stack # - append it to the list # - update curr to be the recently popped node's right node # - however, if the stack is empty in here, we set the while loop to false and exit the function! stack = LinkedStack() # will act as the recursive call curr = self.root # start at the root stillLoop = True # loop until the stack is empty while stillLoop: # we're at the end of a leaf node if curr == None: if stack.length() > 0: node = stack.pop() visit(node.data) curr = node.right # our stack is empty so we can finally return once all the nodes have been visited else: stillLoop = False # we can still go down the left side else: stack.push(curr) curr = curr.left
def _traverse_post_order_iterative(self, node, visit): """Traverse this binary tree with iterative post-order traversal (DFS). Start at the given node and visit each node with the given function. Running time: O(n) Memory usage: O(n) Credit to Nicolai and Ryan for solving what I began""" # Traverse post-order without using recursion (stretch challenge) traversed = set() # Create queue to store nodes not yet traversed stack = LinkedStack() # Enqueue root node as last stack.push(node) while not stack.is_empty(): node = stack.peek() if node.right and node.right not in traversed: stack.push(node.right) if node.left and node.left not in traversed: stack.push(node.left) if ( node.is_leaf() or node.left is None and node.right in traversed or node.left in traversed and node.right is None or node.left in traversed and node.right in traversed ): node = stack.pop() visit(node.data) traversed.add(node)
def _traverse_in_order_iterative(self, node, visit): """Traverse this binary tree with iterative in-order traversal (DFS). Start at the given node and visit each node with the given function. TODO: Running time: ??? Why and under what conditions? TODO: Memory usage: ??? Why and under what conditions?""" stack = LinkedStack() stack.push(node) while stack.is_empty() is False: # add to stack while node.left exist if node.left is not None: # add left, or smaller, node on top stack.push(node.left) # iterate left tree node = node.left # begin iterating right tree else: """once the left tree of node is None, we can begin popping and iterating the right side""" # visit the top node in the stack node = stack.pop() visit(node.data) # iterate the right node since the left node is now empty if node.right is not None: stack.push(node.right) node = node.right
def _traverse_post_order_iterative(self, node, visit): """Traverse this binary tree with iterative post-order traversal (DFS). Start at the given node and visit each node with the given function. TODO: Running time: O(n) because every node is visited TODO: Memory usage: O(log n) we are creating a stack that will hold at most the same number of nodes as height in tree """ # stack to keep track of nodes in order stack = LinkedStack() # done keeps track of if done traversing # controls while loop done = False # set current node to starting node current = node # traverse nodes while stack is not empty while not done: # while current node is something while current: # if right child is there push onto stack if current.right is not None: stack.push(current.right) # push current node onto stack (after right children) stack.push(current) # grab left child of root current = current.left # Current node is none pop node from top of stack current = stack.pop() # check if the node has a right child that hasn't # been checkout yet then push onto stack before current node if current.right is not None and stack.peek() == current.right: # pop child node from stack stack.pop() # push current node onto stack stack.push(current) current = current.right # now set current to right child else: # visit the node visit(current.data) # set current node to None current = None if stack.is_empty(): # stack is empty we are done traversing done = True
def _traverse_in_order_iterative(self, node, visit): """Traverse this binary tree with iterative in-order traversal (DFS). Start at the given node and visit each node with the given function. Running time: O(n) we are visiting each node Memory usage: O(n) creating a stack with number of nodes in the tree""" stack = LinkedStack() stack.push(node) # push the root node while not stack.is_empty(): if (stack.peek().left != None): # if node has left child stack.push(stack.peek().left) else: node = stack.pop() visit(node.data) if (not stack.is_empty()): node = stack.pop() visit(node.data) if (node.right is not None): stack.push(node.right)
class QueueTests(unittest.TestCase): def setUp(self): self.stack = LinkedStack() def test_len_returns_0_for_empty_stack(self): self.assertEqual(len(self.stack), 0) def test_len_returns_correct_length_after_push(self): self.assertEqual(len(self.stack), 0) self.stack.push(2) self.assertEqual(len(self.stack), 1) self.stack.push(4) self.assertEqual(len(self.stack), 2) self.stack.push(6) self.stack.push(8) self.stack.push(10) self.stack.push(12) self.stack.push(14) self.stack.push(16) self.stack.push(18) self.assertEqual(len(self.stack), 9) def test_empty_pop(self): self.assertIsNone(self.stack.pop()) self.assertEqual(len(self.stack), 0) def test_pop_respects_order(self): self.stack.push(100) self.stack.push(101) self.stack.push(105) self.assertEqual(self.stack.pop(), 105) self.assertEqual(len(self.stack), 2) self.assertEqual(self.stack.pop(), 101) self.assertEqual(len(self.stack), 1) self.assertEqual(self.stack.pop(), 100) self.assertEqual(len(self.stack), 0) self.assertIsNone(self.stack.pop()) self.assertEqual(len(self.stack), 0)
def _traverse_in_order_iterative(self): """Traverse this binary tree with iterative in-order traversal (DFS). Start at the given node and visit each node with the given function. TODO: Running time: ??? Why and under what conditions? TODO: Memory usage: ??? Why and under what conditions?""" # TODO: Traverse in-order without using recursion (stretch challenge) items = [] stack = LinkedStack() node = self.root stack.push(node) while stack.is_empty() == False: if node.is_leaf(): items.append(node.data) stack.pop() if stack.is_empty() == False: items.append(stack.peek().data) node = stack.pop().right stack.push(node) else: if node.left is not None: node = node.left stack.push(node) return items
def _traverse_post_order_iterative(self, node, visit): """Traverse this binary tree with iterative post-order traversal (DFS). Start at the given node and visit each node with the given function. Running time: O(n) where n is number of nodes in tree. Memory usage: at most log(n) items since stack having to store at most until the furthest down path.""" # TODO: Traverse post-order without using recursion (stretch challenge) stack = LinkedStack([node]) stack2 = LinkedStack() while stack.is_empty() == False: popped = stack.pop() if popped == None: continue stack2.push(popped) stack.push(popped.left) stack.push(popped.right) # pop items from stack2 and append to items list while stack2.is_empty() == False: visit(stack2.pop().data)
def bracketsBalance(exp): """exp represents the expression""" stk = LinkedStack() # Create a new stack for ch in exp: # Scan across the expression if ch in ['[', '(']: # Push an opening bracket stk.push(ch) elif ch in [']', ')']: # Process a closing bracket if stk.isEmpty(): # Not balanced return False chFromStack = stk.pop() # Brackets must be of same type and match up if ch == ']' and chFromStack != '[' or \ ch == ')' and chFromStack != '(': return False return stk.isEmpty() # They all matched up
def _traverse_pre_order_iterative(self, node, visit): """Traverse this binary tree with iterative pre-order traversal (DFS). Start at the given node and visit each node with the given function. Running time: O(n) we are visiting each node Memory usage: O(n) creating a stack with number of nodes in the tree""" stack = LinkedStack() stack.push(node) while not stack.is_empty(): node = stack.pop() visit(node.data) if (node.right != None): stack.push(node.right) if (node.left != None): stack.push(node.left)
def _traverse_post_order_iterative(self, node, visit): """Traverse this binary tree with iterative post-order traversal (DFS). Start at the given node and visit each node with the given function. Running time: ??? Why and under what conditions? TODO: Memory usage: ??? Why and under what conditions?""" # Traverse post-order without using recursion (stretch challenge) stack = LinkedStack() stack.push(node) while not stack.is_empty(): node = stack.pop() visit(node.data) if node.left: stack.push(node.left) if node.right: stack.push(node.right)
def _traverse_in_order_iterative(self, node, visit): """Traverse this binary tree with iterative in-order traversal (DFS). Start at the given node and visit each node with the given function. TODO: Running time: O(n), have to visit every node TODO: Memory usage: O(n) nodes are stored on stack""" # TODO: Traverse in-order without using recursion (stretch challenge) stack = LinkedStack() node = self.root while ((node is not None) or (not stack.is_empty())): if node is not None: stack.push(node) node = node.left elif not stack.is_empty(): node = stack.pop() visit(node.data) node = node.right
def _traverse_pre_order_iterative(self, node, visit): """Traverse this binary tree with iterative pre-order traversal (DFS). Start at the given node and visit each node with the given function. TODO: Running time: O(n) where n is number of nodes in tree. TODO: Memory usage: at most log(n) items since we're canceling out on the stack each time traversing""" # TODO: Traverse pre-order without using recursion (stretch challenge) stack = LinkedStack([node]) while stack.is_empty() == False: popped = stack.pop() if popped == None: continue visit(popped.data) stack.push(popped.right) stack.push(popped.left)
def _traverse_pre_order_iterative(self, node, visit): """Traverse this binary tree with iterative pre-order traversal (DFS). Start at the given node and visit each node with the given function. Running time: O(3n) because each node is called recursively 3 times. Reduces to O(n) Memory usage: If tree is balanced, height of tree is log(n) and memory usage is O(log(n)) If Tree is unblanced, height of tree is approx n and memory usasge is O(n)""" # Traverse pre-order without using recursion (stretch challenge) stack = LinkedStack() stack.push(node) while not stack.is_empty(): node = stack.pop() visit(node.data) if node.right: stack.push(node.right) if node.left: stack.push(node.left)
def _traverse_in_order_iterative(self, node, visit): """Traverse this binary tree with iterative in-order traversal (DFS). Start at the given node and visit each node with the given function. Running time: O(n) where n is number of nodes since having to visit each node. Memory usage: log(n) items since queue has to store only until at most its subtree until it cancels out?""" stack = LinkedStack() while True: if node == None: if stack.is_empty(): break popped = stack.pop() visit(popped.data) node = popped.right else: stack.push(node) node = node.left
def _traverse_pre_order_iterative(self, node, visit): """Traverse this binary tree with iterative pre-order traversal (DFS). Start at the given node and visit each node with the given function. TODO: Running time: ??? Why and under what conditions? TODO: Memory usage: ??? Why and under what conditions?""" # Traverse pre-order without using recursion (stretch challenge) stack = LinkedStack() # Enstack given starting node stack.push(node) # Loop until queue is empty while not stack.is_empty(): # Dequeue node at front of queue node = stack.pop() # Visit this node's data with given function visit(node.data) # Enqueue this node's left child, if it exists if node.right: stack.push(node.right) # Enqueue this node's right child, if it exists if node.left: stack.push(node.left)
def _traverse_post_order_iterative(self, node, visit): """Traverse this binary tree with iterative post-order traversal (DFS). Start at the given node and visit each node with the given function. TODO: Running time: Why and under what conditions? TODO: Memory usage: ??? Why and under what conditions?""" # Traverse post-order without using recursion stack = LinkedStack() # loop until root node is the current node stack.push(node) while not stack.is_empty():4 node = stack.pop() # look at the top of the stack visit(node.data) # push the right node to the top of the stack if it is not none and it's not in set if node.left is not None: stack.push(node.left) # push the right node to the top of the stack if it is not none and it's not in set if node.right is not None: stack.push(node.right)
def _traverse_post_order_iterative(self, node): """Traverse this binary tree with iterative post-order traversal (DFS). Start at the given node and visit each node with the given function. Running time: O(n) we are visiting each node Memory usage: O(n) creating a stack with number of nodes in the tree""" ''' # Using set and stack stack = Stack() stack.push(node) visited = set() while not stack.is_empty(): if(stack.peek().left != None and stack.peek().left.data not in visited): stack.push(stack.peek().left) elif(stack.peek().right != None and stack.peek().right.data not in visited): stack.push(stack.peek().right) else: node = stack.pop() visit(node.data) visited.add(node.data)''' # create a list equal to size of tree items = [None] * self.size i = self.size # i is the last node stack = LinkedStack() # add the root node to stack stack.push(node) # traverse through stack is empty while not stack.is_empty(): i -= 1 node = stack.pop() # i is the last index and assign it to data at the root items[i] = node.data # check if node has left child and add to stack if it is if (node.left != None): stack.push(node.left) # check if node has right child and add to stack if it is if (node.right != None): stack.push(node.right) return items
def _traverse_in_order_iterative(self, node, visit): """Traverse this binary tree with iterative in-order traversal (DFS). Start at the given node and visit each node with the given function. Running time: O(3n) because each node is called 3 times. Reduces to O(n) Memory usage: If tree is balanced, height of tree is approx log(n) and memory usage is O(log(n)) If Tree is unblanced, height of tree is approx n and memory usasge is O(n)""" # Traverse in-order without using recursion (stretch challenge) stack = LinkedStack() while True: if node == None: if stack.is_empty(): break pop = stack.pop() visit(pop.data) node = pop.right else: stack.push(node) node = node.left