def infixToPostfix(infixexpr): precedence = {} precedence["*"] = 3 precedence["/"] = 3 precedence["+"] = 2 precedence["-"] = 2 precedence["("] = 1 opStack = Stack() postfixList = [] tokenList = infixexpr.split() for token in tokenList: if token in "ABCDEFGHIJKLMNOPQRSTUVWXYZ" or token in "0123456789": postfixList.append(token) elif token == '(': opStack.push(token) elif token == ')': topToken = opStack.pop() while topToken != '(': postfixList.append(topToken) topToken = opStack.pop() else: while (not opStack.isEmpty()) and \ (precedence[opStack.peek()] >= precedence[token]): postfixList.append(opStack.pop()) opStack.push(token) while not opStack.isEmpty(): postfixList.append(opStack.pop()) return " ".join(postfixList)
def parseTree(expression): tokens = expression.split() tree_holder = Stack() main_tree = BinaryTree('') tree_holder.push(main_tree) currentTree = main_tree for val in tokens: if val == '(': currentTree.add_left('') tree_holder.push(currentTree) currentTree = currentTree.get_left() elif val not in '+-*/': currentTree.set_root_val(val) parent = tree_holder.pop() currentTree = parent elif val in '+-*/': currentTree.set_root_val(val) currentTree.add_right('') tree_holder.push(currentTree) currentTree = currentTree.get_right() elif val == ')': currentTree = tree_holder.pop() else: raise ValueError return main_tree
def parenthesis_checker(symbolString): """ Read a string of parenthesis from left to right and decide whether the symbols are balanced """ S = Stack() #Input are valid if symbolString is None: raise TypeError("cannot be none") if not symbolString: raise ValueError("cannot be empty") for char in symbolString: if char == "(": S.push(char) elif char == "[": S.push(char) elif char == "{": S.push(char) else: if S.isEmpty(): return False else: S.pop() return S.isEmpty()
def infixtopostfix(string): comp = string.split(' ') output = [] operator_precedence = {"+": 1, "-": 1, "/": 2, "*": 2, "(": 3, ")": 3} operator_stack = Stack() for value in comp: if value in 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' or value in '0123456789': output.append(value) elif value == '(': operator_stack.push(value) elif value == ')': operator = operator_stack.pop() while operator != '(': output.append(operator) operator = operator_stack.pop() else: while not operator_stack.isEmpty() and \ operator_precedence[operator_stack.peek()] <= operator_precedence[value]: output.append(operator_stack.pop()) operator_stack.push(value) while not operator_stack.isEmpty(): token = operator_stack.pop() output.append(token) return ' '.join(output)
def evaluate_postfix(expr): if len(expr) == 0: return "Expression is invalid" nums = Stack() for char in expr: if char in "+*-": num1 = nums.pop() num2 = nums.pop() if char == "+": subtotal = num1 + num2 elif char == "*": subtotal = num1 * num2 elif char == "-": subtotal = num2 - num1 nums.push(subtotal) else: nums.push(int(char)) if len(nums._items) > 1: return "Expression is invalid" return nums.pop()
def test_pop(self): """ Test Case to test the pop operation """ stack = Stack() stack.push(1) num = stack.pop() self.assertEqual(num, 1) stack.push(2) stack.push(3) num = stack.pop() self.assertEqual(num, 3)
def test_size(self): """ Test Case to check the size of the stack after push and pop operations """ stack = Stack() self.assertEqual(stack.length, 0, STACK_SIZE_ZERO_MSG) stack.push(1) self.assertEqual(stack.length, 1, INCORRECT_STACK_SIZE_MSG) stack.push(2) stack.push(3) self.assertEqual(stack.length, 3, INCORRECT_STACK_SIZE_MSG) stack.pop() self.assertEqual(stack.length, 2, INCORRECT_STACK_SIZE_MSG)
def test_pop_on_empty_stack(self): """ Test Case to test pop operation on Empty Stack """ stack = Stack() stack.push(1) stack.pop() self.assertEqual(stack.length, 0, STACK_SIZE_ZERO_MSG) # Stack should be empty after one push and one pop operation # Should raise EmptyStackException on pop() with self.assertRaises(exceptions.EmptyStackException): stack.pop()
def postfixEval(postfixExpr): operandStack = Stack() tokenList = postfixExpr.split() for token in tokenList: if token.isdigit(): operandStack.push(int(token)) else: operand2 = operandStack.pop() operand1 = operandStack.pop() result = doMath(token, operand1, operand2) operandStack.push(result) return operandStack.pop()
def get_digits(self): """ This pushes numbers in stack. Then it converts that stack into a dictionary value with an alphabetic key. The reason we do this is that the calculations function cannot handle multiple digits because it is processing each element by character. For example, 2 + 2 can be processed but 10 + 10 cannot because it would be expecting a + - * / operator between the 1 and the 0. It is easier to have proxy variables, such as A + B rather than 10 + 10, and use that to pull dictionary values. The result would look like self.numbers.get('A') + self.numbers.get('B') with the self.numbers dictionary looking like {'A': 10, 'B': 10}. The calculator would read this as 10 + 10 without issue. Thus, the purpose of this function is to build that self.numbers dictionary and build self.final_infix with alphabetical variables substituting multi-digit numbers. self.final_infix is a word that looks like 'A+B'. """ operands = Stack() alphabet_num = 65 for char in self.infix_split: if char in '0123456789.': operands.push(char) elif not operands.isempty(): alphabet = chr(alphabet_num) alphabet_num += 1 number = '' # Converts number into a dictionary item. while not operands.isempty(): number = operands.pop() + number self.numbers[alphabet] = number self.final_infix += alphabet + char else: self.final_infix += char
def dft(self, starting_vertex_id): """ Traverse and print each vertex in depth-first order (DFT) beginning from starting_vertex. """ # Initialize empty stack and set of visited nodes: stack = Stack() visited = set() # Check if provided starting vertex is in our graph: if starting_vertex_id in self.vertices.keys(): # If so, add starting vertex to stack: stack.push(starting_vertex_id) else: return IndexError( f"Provided starting vertex {starting_vertex_id} does not exist in graph!" ) # Process all vertices via BFT: while stack.size() > 0: # Get next vertex to process as first item in stack: current_vertex = stack.pop() # If the current vertex has not already been visited+processed, process it: if current_vertex not in visited: # Process current vertex: print(current_vertex) # Add adjacent vertices to stack for future processing: for adjacent_vertex in self.get_neighbors(current_vertex): stack.push(adjacent_vertex) # Mark current vertex as "visited" by adding to our set of visited vertices: visited.add(current_vertex)
def parChecker(symbolString): ''' in: a string containing all symbols return: boolean, true for balaced, vice versa Completed extended parenthesis checker for: [,{,(,),},] ''' leftPar = Stack() strList = list(symbolString) balanced = True symbol = {'[':']','{':'}','(':')'} i = 0 while i < len(symbolString) and balanced: if strList[i] in ['[','(','{']: leftPar.push(strList[i]) else: if leftPar.isEmpty(): balanced = False else: if not strList[i] == symbol[leftPar.pop()]: balanced = False i += 1 if not leftPar.isEmpty(): balanced = False return balanced
def randomize(maze): stack = Stack() current = maze.board[0][0] visited_count = 0 while True: q = current.get_random_nbr() if not current.visited: visited_count += 1 current.visited = True if q is None: if stack.size > 0: current = stack.pop() else: raise StopIteration() else: next, x = q stack.push(current) current.unlock(x) next.unlock((x + 2) % 4) current = next if visited_count >= maze.length * maze.height: raise StopIteration() yield current
def test_top_on_empty_stack(self): """ Test Case to test top property on Empty Stack """ stack = Stack() stack.push(1) top_item = stack.top self.assertEqual(top_item, 1) self.assertEqual(stack.length, 1) stack.pop() self.assertEqual(stack.length, 0, STACK_SIZE_ZERO_MSG) # Should raise EmptyStackException on top on empty stack with self.assertRaises(exceptions.EmptyStackException): stack.top
def test_stack(): stack = Stack() stack.push(3) stack.push(2) assert stack.peek() == 2 assert stack.pop() == 2 assert stack.pop() == 3 assert stack.is_empty()
def paranthesis_checker(string): stack = Stack() balanced = True index = 0 while index < len(string) and balanced: symbol = string[index] if symbol == '(': stack.push(symbol) else: if stack.isEmpty(): balanced = False else: stack.pop() index = index + 1 if balanced and stack.isEmpty(): return True else: return False
def insert_node(self, node): lessFreq_stack = Stack() while self.stack.num_elements>0 and self.stack.top().get_freq() < node.get_freq(): lessFreq_stack.push(self.stack.pop()) self.stack.push(node) while lessFreq_stack.num_elements>0: self.stack.push(lessFreq_stack.pop())
def test_pop(): stack, arr = Stack(), [] assert(stack.is_empty()) with pytest.raises(AssertionError): stack.pop() for _ in range(ITERS): expected = random.randrange(MAX_VAL) stack.push(expected) actual = stack.peek() arr = [expected] + arr assert(len(stack) == len(arr)) assert(actual == expected) for _ in range(ITERS): expected, actual = arr[0], stack.pop() arr = arr[1:] assert(len(stack) == len(arr)) assert(actual == expected) assert(stack.is_empty()) with pytest.raises(AssertionError): stack.pop()
def parens_checker(parens_string): """Checks if parentheses in given string is balanced""" open_parens = Stack() for paren in parens_string: if paren == "(": open_parens.push(paren) else: if open_parens.is_empty(): return False open_parens.pop() # if open_parens: # return False # else: # return True # The above can be simplified to a boolean check of is the stack empty return open_parens.is_empty()
def HexToBinary(number): bin_holder = Stack() while number > 0: rem = number % 2 bin_holder.push(rem) number = number // 2 bin_string = "" while not bin_holder.isEmpty(): bin_string = bin_string + str(bin_holder.pop()) return bin_string
def rev_string(my_string): """Uses stack to reverse characters in string""" chars = Stack() for char in my_string: chars.push(char) reversed_string = '' while not chars.is_empty(): reversed_string += chars.pop() return reversed_string
def dfs(graph: Graph, start_node: str, target_node: str, visited_nodes: set): stack = Stack() stack.push(start_node) while not stack.is_empty(): current = stack.pop() if current == target_node: return True adj = graph.get_edges_node(current) for node in adj: if node not in visited_nodes: stack.push(node) return False
def test_stack(): f = Stack() test_array = [i for i in range(100)] for i in test_array: f.push(i) result = [] while not f.is_empty(): result.append(f.pop()) test_array.reverse() assert test_array == result
def calculations(self): """ This is where the calculator does its magic. To see how this function works, please reference the textbook material on Chapter 3 Stacks. This algorithm was built by making an algorithm that takes an infix expression and transforms it into a postfix expression (2+2 --> 22+). Then, by taking that postfix expression and processing the operators and operands it until there is only 1 element in the stack, we get the postfix answer, which is the same answer for the infix expression. (22+ --> 4) It is possible to build a calculator with simply those 2 algorithms linked up to each other. However, this function is a hybrid of the two where it is able to simultaneously work with operators and operands, such that when an infix expression is determined to be in postfix expression, we immediately calculate the answer. """ precedent = {'*': 3, '/': 3, '+': 2, '-': 2, '(': 1} operator_stack = Stack() operand_stack = Stack() for item in self.final_infix: if item in string.ascii_letters: operand_stack.push(self.numbers.get(item)) elif item == '(': operator_stack.push(item) elif item == ')': # Here be dragons. top_of_stack = operator_stack.pop() while top_of_stack != '(': operand2 = float(operand_stack.pop()) operand1 = float(operand_stack.pop()) operand_stack.push(self.do_math(top_of_stack, operand1, operand2)) top_of_stack = operator_stack.pop() elif item in precedent: while (not operator_stack.isempty()) and precedent[operator_stack.peek()] >= precedent[item]: operand2 = float(operand_stack.pop()) operand1 = float(operand_stack.pop()) operand_stack.push(self.do_math(operator_stack.pop(), operand1, operand2)) operator_stack.push(item) elif item == '~': # This is a helper variable to signal the end of infix expression and empty all stacks. while not operator_stack.isempty(): operand2 = float(operand_stack.pop()) operand1 = float(operand_stack.pop()) operand_stack.push(self.do_math(operator_stack.pop(), operand1, operand2)) else: raise TypeError('Error: Calculations blew up.') self.answer = operand_stack.pop()
def baseConverter(decNum, base): digits = "0123456789ABCDEF" remstack = Stack() while decNum > 0: remainder = decNum % base remstack.push(remainder) decNum = decNum // base newString = "" while not remstack.isEmpty(): newString = newString + digits[remstack.pop()] return newString
def check_balanced_symbols(symbols_string): """Checks if opening and closing symbols in a string are balanced""" open_symbols = Stack() for symbol in symbols_string: if symbol in "({[": open_symbols.push(symbol) elif symbol in ")}]": if open_symbols.is_empty(): return False open_symbol = open_symbols.pop() if not is_matching_symbols(open_symbol, symbol): return False return open_symbols.is_empty()
def revstring(mystr): """ :type mystr: string :rtype: string use Stack Last In First Out feature to reverse a string """ aStack = Stack() for i in list(mystr): aStack.push(i) revstr = "" while not aStack.isEmpty(): revstr += aStack.pop() return revstr
def dfs(grid:np.array, start:tuple, end:tuple, _stack: Stack = Stack()) -> Tuple[list, list]: """ A function that searches for a path in a grid using the Depth-first-search algorithm This function searches through a grid searching for a path using the Depth-first-search algorithm. The function first pushes the first Node object into the stack. A VisitedNodes object is created (visited). While there are objects in the stack, the first node of the stack is removed and appended in visited. The node's position is checked to see if it is equal to the end position; if it is, then a list of visited nodes and a path list is returned. Otherwise, the function iterates over each child of the current node. The child is checked to see if it is in the stack or in visited nodes, and is accessible. If true, the child node is pushed into the stack and the process repeats. Parameters ---------- grid : np.array a numpy array detailing the grid start : tuple a tuple detailing the starting node's position end : tuple a tuple detailing the ending node's position _stack : Stack = Stack() a stack object Returns ------- Tuple[list,list] A list of visited nodes and a list of nodes that are included in the path """ if grid[start[0]][start[1]] == 1 or grid[end[0]][end[1]] == 1: return [None],[None] _stack.push(Node(grid, start)) visited = VisitedNodes() while len(_stack) > 0: node = _stack.pop() visited._store_node(node) if node.pos == end: visited_list,path_list = visited.create_path(node.pos, start) return visited_list,path_list else: for child in node.children: if child["node"] not in visited.visited_nodes and child["node"] not in _stack.stacked_nodes and child["accessibility"]: _stack.push(Node(grid, child["node"], parent=node.pos)) return [None],[None]
def dfs(initial, goal_test, successors): """ Depth-first search. Parameters ---------- initial : Generic Starting point of the search. goal_test : Callable Callable returing boolean value indicating search success. successors : Callable Callable returning list of next possible locations in search space. Returns ------- found : Generic Node corresponding to successful goal_test. Returns None if search fails. """ # References to candidate and previously-explored nodes in search space frontier = Stack() explored = Stack() # Initialize candidate search locations with initial condition frontier.push(Node(initial, None)) # Continue search as long as their are candidates in the search space while not frontier.empty: current_node = frontier.pop() current_state = current_node.state # If current node meets goal, then search completes successfully if goal_test(current_state): return current_node # Populate next step in search for child in successors(current_state): # Skip previously-explored states if child in explored: continue explored.push(child) frontier.push(Node(child, current_node)) # Search terminates without finding goal return None
def parChecker(string): s = Stack() i = 0 balanced = True while i < len(string) and balanced: symbol = string[i] if symbol in "([{": s.push(symbol) elif s.isEmpty(): balanced = False elif symbol in ")]}": top = s.pop() if not matches(top, symbol): balanced = False i += 1 if balanced and s.isEmpty(): return True else: return False
def dfs(self, starting_vertex, target_vertex): """ Return a list containing the shortest path from starting_vertex to destination_vertex, after searching for and finding it with a depth-first search (DFS) algorithm. """ # Initialize empty stack and set of visited nodes: stack = Stack() visited = set() # Initialize path (we will add the rest of the path from starting vertex to target vertex below): path = [starting_vertex] # Check if provided starting vertex is in our graph: if starting_vertex in self.vertices.keys(): # If so, add starting vertex to stack: stack.push(path) else: return IndexError( f"Provided starting vertex {starting_vertex} does not exist in graph!" ) # Process all vertices via BFT: while stack.size() > 0: # Get next vertex to process as first item in stack: current_path = stack.pop() current_vertex = current_path[-1] # If the current vertex has not already been visited+processed, check and process it: if current_vertex not in visited: # Check if it is the target --> if so, return its full path: if current_vertex == target_vertex: return current_path # If not, then get its neighbor vertices and add their paths to the stack for future processing: for adjacent_vertex in self.get_neighbors(current_vertex): adjacent_vertex_path = current_path + [adjacent_vertex] stack.push(adjacent_vertex_path) # Mark current vertex as "visited" by adding to our set of visited vertices: visited.add(current_vertex) # If no path found in entire graph, return None: return None
def baseConverter(decNumber,base): ''' decNumber: decimal number base: int between 2 and 16 Algorithm for binary conversion can easily be extended to perform the conversion for any base. In computer science it is common to use a number of different encodings. The most common of these are binary, octal (base 8) , and hexadecimal (base 16). ''' baseNumber = '' reminders = Stack() while decNumber > 0: reminders.push(decNumber%base) decNumber = decNumber//base while not reminders.isEmpty(): baseNumber += str(reminders.pop()) return baseNumber
def attempt_2(self, head: ListNode, k: int) -> ListNode: """ Better solution: Insert all elements into a stack and pop k elements. The last popped is returned. Don't need to know the length of the list in this algorithm. :param head: head of list :param k: parameter, k :return: returns the k'th to last element :Time: O(N) :Space: O(N) """ stack = Stack() curr = head while curr is not None: stack.push(curr) curr = curr.next ret_val = None for i in range(k): popped = stack.pop() if i == k - 1: ret_val = popped return ret_val
class TestStack(unittest.TestCase): # LIFO def setUp(self): self.emptyStack = Stack() self.Stack = Stack() for i in range(5): self.Stack.push(i) def test_repr(self): '''Test returning the stack as a string literal.''' self.assertEqual(repr(self.emptyStack), str(())) tup = (1, 3.14, 'foo', True) for i in tup: self.emptyStack.push(i) self.assertEqual(repr(self.emptyStack), str((True, 'foo', 3.14, 1))) def test_len_size(self): '''Test returning the size of the stack.''' for i in range(100): self.emptyStack.push(i) self.assertEqual(len(self.emptyStack), 100) self.assertEqual(self.emptyStack.size(), 100) self.emptyStack.pop() self.assertEqual(len(self.emptyStack), 99) self.assertEqual(self.emptyStack.size(), 99) def test_tuple(self): '''Test returning the stack as a tuple literal.''' self.assertEqual(tuple(self.emptyStack), ()) tup = (1, 3.14, 'foo', True) for i in tup: self.emptyStack.push(i) self.assertEqual(tuple(self.emptyStack), (True, 'foo', 3.14, 1)) def test_list(self): '''Test returning the stack as a list literal.''' self.assertEqual(list(self.emptyStack), []) li = [1, 3.14, 'foo', True] for i in li: self.emptyStack.push(i) self.assertEqual(list(self.emptyStack), [True, 'foo', 3.14, 1]) def test_push(self): '''Test pushing items on top of the stack.''' self.Stack.push(True) self.assertEqual(tuple(self.Stack), (True, 4, 3, 2, 1, 0)) def test_pop(self): '''Test popping off and returning the top of the stack.''' self.assertEqual(self.Stack.pop(), 4) self.assertEqual(tuple(self.Stack), (3, 2, 1, 0)) self.assertEqual(self.Stack.pop(), 3) self.assertEqual(self.Stack.pop(), 2) self.assertEqual(self.Stack.pop(), 1) self.assertEqual(self.Stack.pop(), 0) self.assertEqual(tuple(self.Stack), ()) with self.assertRaises(ValueError): self.Stack.pop() def test_peek(self): '''Test peeking at the top of the stack w/o modifying the stack.''' self.assertEqual(self.Stack.peek(), 4) with self.assertRaises(ValueError): self.emptyStack.peek()
class TestDataStructures(unittest.TestCase): def setUp(self): self.stack = Stack(range(1, 6)) self.queue = Queue(range(1, 6)) self.single = SinglyLinkedList() self.double = DoublyLinkedList() self.btree = BinaryTree() # STACK def test_stack_push(self): self.stack.push(6) self.assertEqual(self.stack.stack, range(1, 7)) def test_stack_pop(self): self.assertEqual(self.stack.pop(), 5) self.assertEqual(self.stack.pop(), 4) def test_stack_peek(self): self.assertEqual(self.stack.peek(), 5) # QUEUE def test_queue_push(self): self.queue.push(6) self.assertEqual(self.queue.queue, range(1, 7)) def test_queue_pop(self): self.assertEqual(self.queue.pop(), 1) self.assertEqual(self.queue.pop(), 2) def test_queue_peek(self): self.assertEqual(self.queue.peek(), 1) self.queue.pop() self.assertEqual(self.queue.peek(), 2) # SINGLY-LINKED LIST def test_add_nodes_to_single(self): node1, node2, node3 = Node(1), Node(2), Node(3) self.single._insert(node1) self.single._insert(node2, node1) self.assertEqual(self.single.head.value, 1) next = self.single.head.next self.assertEqual(next, node2) self.assertEqual(next.value, 2) self.single._insert(node3, node2) nextnext = self.single.head.next.next self.assertEqual(nextnext, node3) def test_add_node_to_beginning_of_single(self): node0, node1 = Node(0), Node(1) self.single._insert(node1) self.single._insert(node0) self.assertEqual(self.single.head.value, 0) self.assertEqual(self.single.head.next.value, 1) def test_remove_nodes_single(self): node1, node2, node3, node4 = Node(1), Node(2), Node(3), Node(4) self.single._insert(node1) self.single._insert(node2, node1) self.single._insert(node3, node2) self.single._insert(node4, node3) self.single._remove(node2) self.assertEqual(node2.next, node4) def test_remove_node_from_beginning_single(self): node1, node2, node3 = Node(1), Node(2), Node(3) self.single._insert(node1) self.single._insert(node2, node1) self.single._insert(node3, node2) self.single._remove() self.assertEqual(self.single.head, node2) def test_single_iteration(self): node1, node2, node3, node4 = Node(1), Node(2), Node(3), Node(4) self.single._insert(node1) self.single._insert(node2, node1) self.single._insert(node3, node2) self.single._insert(node4, node3) self.assertEqual([node for node in self.single], [node1, node2, node3, node4]) def test_add_node_to_single_for_real(self): self.single.insert(2, 0) self.assertEqual(self.single[0].value, 2) self.single.insert(1, 0) self.assertEqual(self.single[0].value, 1) self.single.insert(3, 2) self.assertEqual(self.single[2].value, 3) self.single.insert(4, 100) self.assertEqual(self.single[3].value, 4) def test_remove_node_from_single_for_real(self): for i in range(4, 0, -1): self.single.insert(i, 0) # [1, 2, 3, 4] self.single.remove(1) # [1, 3, 4] self.assertEqual(self.single[1].value, 3) self.single.remove(2) # [1, 3] self.assertEqual(self.single[0].value, 1) self.assertEqual(self.single[1].value, 3) # DOUBLE-LINKED LIST def test_iteration_double(self): node1, node2, node3 = Node(1), Node(2), Node(3) node1.next, node2.next, node3.next = node2, node3, None node1.prev, node2.prev, node3.prev = None, node1, node2 self.double.head = node1 self.double.tail = node3 # test __iter__ self.assertEqual([str(i) for i in self.double], [str(i) for i in range(1, 4)]) # test iterating over reversed self.assertEqual([str(i) for i in reversed(self.double)], [str(i) for i in range(3, 0, -1)]) def test_double_slicing(self): node1, node2, node3 = Node(1), Node(2), Node(3) node1.next, node2.next, node3.next = node2, node3, None node1.prev, node2.prev, node3.prev = None, node1, node2 self.double.head = node1 self.double.tail = node3 self.assertEqual(self.double[0].value, 1) self.assertEqual(self.double[1].value, 2) self.assertEqual(self.double[2].value, 3) self.assertRaises(IndexError, lambda val: self.double[val], 3) def test_base_insert_moving_forwards_with_double(self): node1, node2, node3 = Node(1), Node(2), Node(3) self.double._insert(node1) self.assertTrue(test_node(self.double[0], 1, None, None)) self.assertTrue(test_linked_list(self.double, self.double[0], self.double[0])) self.double._insert(node3, node1) self.assertTrue(test_node(self.double[0], 1, 3, None)) self.assertTrue(test_node(self.double[1], 3, None, 1)) self.assertTrue(test_linked_list(self.double, self.double[0], self.double[1])) self.double._insert(node2, node1) self.assertTrue(test_node(self.double[0], 1, 2, None)) self.assertTrue(test_node(self.double[1], 2, 3, 1)) self.assertTrue(test_node(self.double[2], 3, None, 2)) self.assertTrue(test_linked_list(self.double, self.double[0], self.double[2])) self.assertEqual(str(self.double), str([str(i) for i in range(1, 4)])) def test_base_insert_moving_backwards_with_double(self): node1, node2, node3 = Node(1), Node(2), Node(3) # insert node3 at the beginning/end of the list self.double._rev_insert(node3) self.assertTrue(test_node(self.double[0], 3, None, None)) self.assertTrue(test_linked_list(self.double, self.double[0], self.double[0])) # insert node one before node 3 ([node1, node3]) self.double._rev_insert(node1, node3) self.assertTrue(test_node(self.double[0], 1, 3, None)) self.assertTrue(test_node(self.double[1], 3, None, 1)) self.assertTrue(test_linked_list(self.double, self.double[0], self.double[1])) # insert node2 before node3 ([node1, node2, node3]) self.double._rev_insert(node2, node3) self.assertTrue(test_node(self.double[0], 1, 2, None)) self.assertTrue(test_node(self.double[1], 2, 3, 1)) self.assertTrue(test_node(self.double[2], 3, None, 2)) self.assertTrue(test_linked_list(self.double, self.double[0], self.double[2])) # check that the array is [node1, node2, node3] self.assertEqual(str(self.double), str([str(i) for i in range(1, 4)])) def test_insert_at_beginning_of_double(self): self.double.insert(2, 0) self.assertTrue(test_node(self.double[0], 2, None, None)) self.assertTrue(test_linked_list(self.double, self.double[0], self.double[0])) self.double.insert(1, 0) self.assertTrue(test_node(self.double[0], 1, 2, None)) self.assertTrue(test_node(self.double[1], 2, None, 1)) self.assertTrue(test_linked_list(self.double, self.double[0], self.double[1])) def test_insert_in_middle_and_end_of_double(self): self.double.insert(1, 0) self.double.insert(3, 1) self.assertTrue(test_node(self.double[0], 1, 3, None)) self.assertTrue(test_node(self.double[1], 3, None, 1)) self.assertTrue(test_linked_list(self.double, self.double[0], self.double[1])) self.double.insert(2, 1) self.assertTrue(test_node(self.double[0], 1, 2, None)) self.assertTrue(test_node(self.double[1], 2, 3, 1)) self.assertTrue(test_node(self.double[2], 3, None, 2)) self.assertTrue(test_linked_list(self.double, self.double[0], self.double[2])) self.double.insert(5, 3) self.assertTrue(test_node(self.double[0], 1, 2, None)) self.assertTrue(test_node(self.double[1], 2, 3, 1)) self.assertTrue(test_node(self.double[2], 3, 5, 2)) self.assertTrue(test_node(self.double[3], 5, None, 3)) self.assertTrue(test_linked_list(self.double, self.double[0], self.double[3])) self.double.insert(4, 3) self.assertTrue(test_node(self.double[0], 1, 2, None)) self.assertTrue(test_node(self.double[1], 2, 3, 1)) self.assertTrue(test_node(self.double[2], 3, 4, 2)) self.assertTrue(test_node(self.double[3], 4, 5, 3)) self.assertTrue(test_node(self.double[4], 5, None, 4)) self.assertTrue(test_linked_list(self.double, self.double[0], self.double[4])) # Binary Tree def test_binary_node_equality(self): one = BinaryNode(1) one2 = BinaryNode(1) self.assertTrue(one == one2) two = BinaryNode(2) self.assertFalse(one == two) def test_add_internal_child_to_binary_node(self): one = BinaryNode(1) two = BinaryNode(2) three = BinaryNode(3) one.left = three # one = {left: 3, right: None} one.insert(two, three) self.assertTrue(test_binary_node(one, 1, 2, None, None)) self.assertTrue(test_binary_node(two, 2, 3, None, 1)) self.assertTrue(test_binary_node(three, 3, None, None, 2)) def test_add_external_child_to_binary_node(self): one = BinaryNode(1) two = BinaryNode(2) one.insert(two) self.assertTrue(test_binary_node(one, 1, 2, None, None)) self.assertTrue(test_binary_node(two, 2, None, None, 1)) three = BinaryNode(3) one.insert(three) self.assertTrue(test_binary_node(one, 1, 2, 3, None)) self.assertTrue(test_binary_node(two, 2, None, None, 1)) self.assertTrue(test_binary_node(three, 3, None, None, 1)) four = BinaryNode(4) two.insert(four) self.assertTrue(test_binary_node(two, 2, 4, None, 1)) self.assertTrue(test_binary_node(four, 4, None, None, 2)) def test_depth_first_generation(self): self.btree.root = deep_btree() self.assertEquals([int(str(n)) for n in self.btree.depth_gen(self.btree.root)], range(1, 9)) def test_breadth_first_generation(self): self.btree.root = wide_btree() self.assertEqual([int(str(n)) for n in self.btree.breadth_gen([self.btree.root])], range(1, 9)) def test_binary_tree_iteration(self): self.btree.root = deep_btree() self.assertEquals([int(str(n)) for n in self.btree], range(1, 9)) def test_contains(self): self.btree.root = deep_btree() for i in range(1, 9): self.assertTrue(i in self.btree) self.assertFalse(0 in self.btree) self.assertFalse(9 in self.btree) def test_insert_into_binary_tree(self): ## note - indexing grabs the node with that VALUE, not the node that exists at that index # 1 self.btree.insert(1) self.assertTrue(test_binary_node(self.btree[1], 1, None, None, None)) self.btree.insert(4, 1) # 1 # / # 4 self.assertTrue(test_binary_node(self.btree[1], 1, 4, None, None)) self.assertTrue(test_binary_node(self.btree[4], 4, None, None, 1)) self.btree.insert(3, 1) # 1 # / \ # 4 3 self.assertTrue(test_binary_node(self.btree[1], 1, 4, 3, None)) self.assertTrue(test_binary_node(self.btree[4], 4, None, None, 1)) self.assertTrue(test_binary_node(self.btree[3], 3, None, None, 1)) self.btree.insert(2, 1, 4) # 1 # / \ # 2 3 # / # 4 self.assertTrue(test_binary_node(self.btree[1], 1, 2, 3, None)) self.assertTrue(test_binary_node(self.btree[2], 2, 4, None, 1)) self.assertTrue(test_binary_node(self.btree[3], 3, None, None, 1)) self.assertTrue(test_binary_node(self.btree[4], 4, None, None, 2)) # Binary Search Tree def test_binary_search_node(self): root = binary_search_tree() for i in range(1, 9): self.assertTrue(root.search(i)) self.assertFalse(root.search(0)) self.assertFalse(root.search(9)) def test_binary_search_insert(self): # 5 # / \ # 3 8 # / \ / # 2 4 6 root = BinarySearchNode(5) self.assertTrue(test_binary_node(root, 5, None, None, None)) root.insert(3) self.assertTrue(test_binary_node(root, 5, 3, None, None)) self.assertTrue(test_binary_node(root[3], 3, None, None, 5)) root.insert(8) self.assertTrue(test_binary_node(root, 5, 3, 8, None)) self.assertTrue(test_binary_node(root[3], 3, None, None, 5)) self.assertTrue(test_binary_node(root[8], 8, None, None, 5)) root.insert(4) self.assertTrue(test_binary_node(root, 5, 3, 8, None)) self.assertTrue(test_binary_node(root[3], 3, None, 4, 5)) self.assertTrue(test_binary_node(root[8], 8, None, None, 5)) self.assertTrue(test_binary_node(root[4], 4, None, None, 3)) root.insert(2) self.assertTrue(test_binary_node(root, 5, 3, 8, None)) self.assertTrue(test_binary_node(root[3], 3, 2, 4, 5)) self.assertTrue(test_binary_node(root[8], 8, None, None, 5)) self.assertTrue(test_binary_node(root[2], 2, None, None, 3)) self.assertTrue(test_binary_node(root[4], 4, None, None, 3)) root.insert(6) self.assertTrue(test_binary_node(root, 5, 3, 8, None)) self.assertTrue(test_binary_node(root[3], 3, 2, 4, 5)) self.assertTrue(test_binary_node(root[8], 8, 6, None, 5)) self.assertTrue(test_binary_node(root[2], 2, None, None, 3)) self.assertTrue(test_binary_node(root[4], 4, None, None, 3)) self.assertTrue(test_binary_node(root[6], 6, None, None, 8)) # def test_binary_search_remove_external_node(self): # root = binary_search_tree() # root.remove(1) # self.assertTrue(test_binary_node(root, 5, 3, 8, None)) # self.assertTrue(test_binary_node(root[3], 3, 2, 4, 5)) # self.assertTrue(test_binary_node(root[8], 8, 6, None, 5)) # self.assertTrue(test_binary_node(root[2], 2, None, None, 3)) # self.assertTrue(test_binary_node(root[4], 4, None, None, 3)) # self.assertTrue(test_binary_node(root[6], 6, None, 7, 8)) # self.assertTrue(test_binary_node(root[7], 7, None, None, 6)) # self.assertFalse(1 in root) # self.assertFalse(root.search(1)) def test_binary_search_remove_internal_node_without_children(self): root = binary_search_tree() root.remove(3, root[4]) self.assertTrue(test_binary_node(root, 5, 4, 8, None)) self.assertTrue(test_binary_node(root[4], 4, 2, None, 5)) self.assertTrue(test_binary_node(root[8], 8, 6, None, 5)) self.assertTrue(test_binary_node(root[2], 2, 1, None, 4)) self.assertTrue(test_binary_node(root[6], 6, None, 7, 8)) self.assertTrue(test_binary_node(root[7], 7, None, None, 6)) self.assertFalse(3 in root) def test_binary_search_remove_internal_node_with_children1(self): root = binary_search_tree() root.insert(3.5) root.insert(4.5) root.remove(3, root[4]) self.assertTrue(test_binary_node(root, 5, 4, 8, None)) self.assertTrue(test_binary_node(root[4], 4, 3.5, 4.5, 5)) self.assertTrue(test_binary_node(root[8], 8, 6, None, 5)) self.assertTrue(test_binary_node(root[2], 2, 1, None, 3.5)) self.assertTrue(test_binary_node(root[6], 6, None, 7, 8)) self.assertTrue(test_binary_node(root[1], 1, None, None, 2)) self.assertTrue(test_binary_node(root[3.5], 3.5, 2, None, 4)) self.assertTrue(test_binary_node(root[4.5], 4.5, None, None, 4)) self.assertTrue(test_binary_node(root[7], 7, None, None, 6)) self.assertFalse(3 in root) def test_binary_search_remove_internal_node_with_children2(self): root = binary_search_tree() root.insert(3.5) root.insert(4.5) root.remove(3, root[2]) self.assertTrue(test_binary_node(root, 5, 2, 8, None)) self.assertTrue(test_binary_node(root[2], 2, 1, 4, 5)) self.assertTrue(test_binary_node(root[8], 8, 6, None, 5)) self.assertTrue(test_binary_node(root[6], 6, None, 7, 8)) self.assertTrue(test_binary_node(root[1], 1, None, None, 2)) self.assertTrue(test_binary_node(root[4], 4, 3.5, 4.5, 2)) self.assertTrue(test_binary_node(root[3.5], 3.5, None, None, 4)) self.assertTrue(test_binary_node(root[4.5], 4.5, None, None, 4)) self.assertTrue(test_binary_node(root[7], 7, None, None, 6)) self.assertFalse(3 in root) # HEAP def test_heap_iteration(self): heap = Heap(max_heap()) self.assertEqual([int(str(n)) for n in heap.breadth()], [17, 15, 10, 6, 10, 7]) self.assertEqual([int(str(n)) for n in heap], [17, 15, 10, 6, 10, 7]) self.assertEqual(heap.flatten(), [17, 15, 10, 6, 10, 7]) def test_find_open_with_empty_aunt(self): node17 = HeapNode(17) node15 = HeapNode(15) node11 = HeapNode(11) node6 = HeapNode(6) node10 = HeapNode(10) node17.left = node15 node17.right = node11 node15.left = node6 node15.right = HeapNode(10) heap = Heap(node17) self.assertEqual(heap[-1].value, 10) self.assertEqual(heap.find_open(), (node11, 'left')) def test_find_open_with_single_child_aunt(self): node17 = HeapNode(17) node15 = HeapNode(15) node11 = HeapNode(11) node6 = HeapNode(6) node10 = HeapNode(10) node7 = HeapNode(7) node17.left = node15 node17.right = node11 node15.left = node6 node15.right = HeapNode(10) node11.left = node7 heap = Heap(node17) self.assertEqual(heap[-1].value, 7) self.assertEqual(heap.find_open(), (node11, 'right')) def test_find_open_with_non_empty_aunt(self): node17 = HeapNode(17) node15 = HeapNode(15) node11 = HeapNode(11) node6 = HeapNode(6) node10 = HeapNode(10) node7 = HeapNode(7) node5 = HeapNode(5) node17.left = node15 node17.right = node11 node15.left = node6 node15.right = HeapNode(10) node11.left = node7 node11.right = node5 heap = Heap(node17) self.assertEqual(heap[-1].value, 5) self.assertEqual(heap.find_open(), (node6, 'left')) def test_insert(self): node17 = HeapNode(17) heap = Heap(node17) heap.insert(15) self.assertTrue(test_binary_node(heap.root, 17, 15, None, None)) self.assertTrue(test_binary_node(heap.root.left, 15, None, None, 17)) heap.insert(10) self.assertTrue(test_binary_node(heap.root, 17, 15, 10, None)) self.assertTrue(test_binary_node(heap.root.left, 15, None, None, 17)) self.assertTrue(test_binary_node(heap.root.right, 10, None, None, 17)) heap.insert(6) self.assertTrue(test_binary_node(heap.root, 17, 15, 10, None)) self.assertTrue(test_binary_node(heap.root.left, 15, 6, None, 17)) self.assertTrue(test_binary_node(heap.root.right, 10, None, None, 17)) self.assertTrue(test_binary_node(heap.root.left.left, 6, None, None, 15)) heap.insert(10) self.assertTrue(test_binary_node(heap.root, 17, 15, 10, None)) self.assertTrue(test_binary_node(heap.root.left, 15, 6, 10, 17)) self.assertTrue(test_binary_node(heap.root.right, 10, None, None, 17)) self.assertTrue(test_binary_node(heap.root.left.left, 6, None, None, 15)) self.assertTrue(test_binary_node(heap.root.left.right, 10, None, None, 15)) heap.insert(7) self.assertTrue(test_binary_node(heap.root, 17, 15, 10, None)) self.assertTrue(test_binary_node(heap.root.left, 15, 6, 10, 17)) self.assertTrue(test_binary_node(heap.root.right, 10, 7, None, 17)) self.assertTrue(test_binary_node(heap.root.left.left, 6, None, None, 15)) self.assertTrue(test_binary_node(heap.root.left.right, 10, None, None, 15)) self.assertTrue(test_binary_node(heap.root.right.left, 7, None, None, 10)) def test_bubble(self): # 17 17 100 # / \ / \ / \ # 15 10 --> 15 100 --> 15 17 # / \ / \ / \ / \ / \ / \ # 6 10 7 100 6 10 7 10 6 10 7 10 heap = Heap(max_heap()) parent = heap.root.right last = HeapNode(100) parent.right = last last.parent = parent heap.bubble(last) self.assertTrue(test_binary_node(heap.root, 100, 15, 17, None)) self.assertTrue(test_binary_node(heap.root.right, 17, 7, 10, 100)) self.assertTrue(test_binary_node(heap.root.right.left, 7, None, None, 17)) self.assertTrue(test_binary_node(heap.root.right.right, 10, None, None, 17)) # 100 100 100 # / \ / \ / \ # 15 17 --> 15 17 --> 99 17 # / \ / \ / \ / \ / \ / \ # 6 10 7 10 99 10 7 10 15 10 7 10 # / / / # 99 6 6 parent = heap.root.left.left last = HeapNode(99) last.parent = parent parent.left = last heap.bubble(last) self.assertTrue(test_binary_node(heap.root, 100, 99, 17, None)) self.assertTrue(test_binary_node(heap.root.left, 99, 15, 10, 100)) self.assertTrue(test_binary_node(heap.root.left.left, 15, 6, None, 99)) self.assertTrue(test_binary_node(heap.root.left.right, 10, None, None, 99)) self.assertTrue(test_binary_node(heap.root.left.left.left, 6, None, None, 15)) # 100 100 100 # / \ / \ / \ # 99 17 --> 99 17 --> 100 17 # / \ / \ / \ / \ / \ / \ # 15 10 7 10 15 100 7 10 15 99 7 10 # / \ / / \ / / \ / # 6 12 100 6 12 10 6 12 10 fifteen = heap.root.left.left twelve = HeapNode(12) twelve.parent = fifteen fifteen.right = twelve ten = heap.root.left.right last = HeapNode(100) ten.left = last last.parent = ten heap.bubble(last) self.assertTrue(test_binary_node(heap.root, 100, 100, 17, None)) self.assertTrue(test_binary_node(heap.root.left, 100, 15, 99, 100)) self.assertTrue(test_binary_node(heap.root.left.left, 15, 6, 12, 100)) self.assertTrue(test_binary_node(heap.root.left.right, 99, 10, None, 100)) def test_insertion_with_percolation(self): # 17 # / \ # 15 10 # / \ / # 6 10 7 # 6 six = HeapNode(6) heap = Heap(six) self.assertTrue(test_binary_node(heap.root, 6, None, None, None)) # 6 10 # / --> / # 10 6 heap.insert(10) self.assertTrue(test_binary_node(heap.root, 10, 6, None, None)) self.assertTrue(test_binary_node(heap.root.left, 6, None, None, 10)) # 10 10 # / \ --> / \ # 6 7 6 7 heap.insert(7) self.assertTrue(test_binary_node(heap.root, 10, 6, 7, None)) self.assertTrue(test_binary_node(heap.root.left, 6, None, None, 10)) self.assertTrue(test_binary_node(heap.root.right, 7, None, None, 10)) # 10 15 # / \ --> / \ # 6 7 10 7 # / / # 15 6 heap.insert(15) self.assertTrue(test_binary_node(heap.root, 15, 10, 7, None)) self.assertTrue(test_binary_node(heap.root.left, 10, 6, None, 15)) self.assertTrue(test_binary_node(heap.root.right, 7, None, None, 15)) self.assertTrue(test_binary_node(heap.root.left.left, 6, None, None, 10)) # 15 17 # / \ --> / \ # 10 7 15 7 # / \ / \ # 6 17 6 10 heap.insert(17) self.assertTrue(test_binary_node(heap.root, 17, 15, 7, None)) self.assertTrue(test_binary_node(heap.root.left, 15, 6, 10, 17)) self.assertTrue(test_binary_node(heap.root.right, 7, None, None, 17)) self.assertTrue(test_binary_node(heap.root.left.left, 6, None, None, 15)) self.assertTrue(test_binary_node(heap.root.left.right, 10, None, None, 15)) # 17 17 # / \ --> / \ # 15 7 15 11 # / \ / / \ / # 6 10 11 6 10 7 heap.insert(11) self.assertTrue(test_binary_node(heap.root, 17, 15, 11, None)) self.assertTrue(test_binary_node(heap.root.left, 15, 6, 10, 17)) self.assertTrue(test_binary_node(heap.root.right, 11, 7, None, 17)) self.assertTrue(test_binary_node(heap.root.left.left, 6, None, None, 15)) self.assertTrue(test_binary_node(heap.root.left.right, 10, None, None, 15)) self.assertTrue(test_binary_node(heap.root.right.left, 7, None, None, 11)) def test_build_from_array(self): heap1 = [17, 15, 11, 6, 10, 7] heap2 = [6, 10, 7, 15, 17, 11] heap = Heap(array=heap1) self.assertTrue(test_binary_node(heap.root, 17, 15, 11, None)) self.assertTrue(test_binary_node(heap.root.left, 15, 6, 10, 17)) self.assertTrue(test_binary_node(heap.root.right, 11, 7, None, 17)) self.assertTrue(test_binary_node(heap.root.left.left, 6, None, None, 15)) self.assertTrue(test_binary_node(heap.root.left.right, 10, None, None, 15)) self.assertTrue(test_binary_node(heap.root.right.left, 7, None, None, 11)) heap = Heap(array=heap2) self.assertTrue(test_binary_node(heap.root, 17, 15, 11, None)) self.assertTrue(test_binary_node(heap.root.left, 15, 6, 10, 17)) self.assertTrue(test_binary_node(heap.root.right, 11, 7, None, 17)) self.assertTrue(test_binary_node(heap.root.left.left, 6, None, None, 15)) self.assertTrue(test_binary_node(heap.root.left.right, 10, None, None, 15)) self.assertTrue(test_binary_node(heap.root.right.left, 7, None, None, 11)) def test_delete(self): # 17 7 15 15 # / \ / \ / \ / \ # 15 11 --> 15 11 --> 7 11 --> 10 11 # / \ / / \ / \ / \ # 6 10 7 6 10 6 10 6 7 heap = Heap(max_heap()) heap[2].value = 11 heap.delete_root() self.assertTrue(test_binary_node(heap.root, 15, 10, 11, None)) self.assertTrue(test_binary_node(heap.root.left, 10, 6, 7, 15)) self.assertTrue(test_binary_node(heap.root.right, 11, None, None, 15)) self.assertTrue(test_binary_node(heap.root.left.left, 6, None, None, 10)) self.assertTrue(test_binary_node(heap.root.left.right, 7, None, None, 10)) # 15 7 11 # / \ / \ / \ # 10 11 --> 10 11 --> 10 7 # / \ / / # 6 7 6 6 heap.delete_root() self.assertTrue(test_binary_node(heap.root, 11, 10, 7, None)) self.assertTrue(test_binary_node(heap.root.left, 10, 6, None, 11)) self.assertTrue(test_binary_node(heap.root.right, 7, None, None, 11)) self.assertTrue(test_binary_node(heap.root.left.left, 6, None, None, 10)) # 11 6 10 # / \ / \ / \ # 10 7 --> 10 7 --> 6 7 # / # 6 heap.delete_root() self.assertTrue(test_binary_node(heap.root, 10, 6, 7, None)) self.assertTrue(test_binary_node(heap.root.left, 6, None, None, 10)) self.assertTrue(test_binary_node(heap.root.right, 7, None, None, 10)) # 10 7 # / \ --> / # 6 7 6 heap.delete_root() self.assertTrue(test_binary_node(heap.root, 7, 6, None, None)) self.assertTrue(test_binary_node(heap.root.left, 6, None, None, 7)) # 7 # / --> 6 # 6 heap.delete_root() self.assertTrue(test_binary_node(heap.root, 6, None, None, None)) # 6 --> None heap.delete_root() self.assertFalse(heap.root)