def test_leaves_basic(self): """ Tests the leaves returned from a tree with a root and two children """ nodes = BinaryTreeNode(1, BinaryTreeNode(2), BinaryTreeNode(3)) bt = BinaryTree(nodes) self.assertListEqual(list(bt.get_leaves()), [nodes.left, nodes.right])
def test_preorder(self): """ Tests the nodes returned by a pre-order traversal of a 3-generation tree """ leaf1, leaf2, leaf3 = BinaryTreeNode(10), BinaryTreeNode(20), BinaryTreeNode(30) parent1, parent2 = BinaryTreeNode(5, leaf1, leaf2), BinaryTreeNode(15, leaf3) root = BinaryTreeNode(0, parent1, parent2) bt = BinaryTree(root) self.assertListEqual(list(bt.get_preorder()), [root, parent1, leaf1, leaf2, parent2, leaf3])
def test_leaves_complex(self): """ Tests the leaves returned from a 3-generation tree with different configurations of children """ leaf1, leaf2, leaf3 = BinaryTreeNode(10), BinaryTreeNode(20), BinaryTreeNode(30) parent1, parent2 = BinaryTreeNode(5, leaf1, leaf2), BinaryTreeNode(15, leaf3) root = BinaryTreeNode(0, parent1, parent2) bt = BinaryTree(root) self.assertListEqual(list(bt.get_leaves()), [leaf1, leaf2, leaf3])
def test_constructor(self): """ Tests the state of a binary tree's root after initialization """ try: # test invalid tree creation bt = BinaryTree(None) self.assertTrue(False) except ValueError: bt = BinaryTree(BinaryTreeNode(1)) self.assertEqual(bt.root.val, 1)
def suffix_to_tree(self): node_stack = Stack() op_num = 0 for elm in self.exp_elements_suffix: node = Node() if elm < Const.Min: node.type = Const.NumNode node.num = Num(elm) else: op_num += 1 node.type = Const.OpNode node.right = node_stack.pop() node.left = node_stack.pop() node.op = elm node_stack.push(node) self.tree = BinaryTree(node_stack.pop(), op_num)
def test_equivalent(self): """ Tests whether tree equivalence with both equivalent and non-equivalent trees """ bt1 = BinaryTree(BinaryTreeNode(1, BinaryTreeNode(2), BinaryTreeNode(3))) bt2 = BinaryTree(BinaryTreeNode(1, BinaryTreeNode(2), BinaryTreeNode(3))) self.assertTrue(bt1.is_equivalent(bt2)) bt3 = BinaryTree(BinaryTreeNode(1)) self.assertFalse(bt1.is_equivalent(bt3)) bt4 = BinaryTree(BinaryTreeNode(1, BinaryTreeNode(3), BinaryTreeNode(2))) self.assertFalse(bt1.is_equivalent(bt4))
def test_add_card_one_not_ace(self): """ Tests the state of adding 1 non-ace card to the hand """ h = Hand() card = Card('king', [10]) h.add_card(card) self.assertListEqual(list(h.get_possible_scores()), [10]) self.assertListEqual(list(h.get_cards()), [card]) expected_tree = BinaryTree(BinaryTreeNode(0, BinaryTreeNode(10))) self.assertTrue(h.hands.is_equivalent(expected_tree))
def test_add_card_multiple_no_ace(self): """ Tests the state of adding multiple non-ace cards to the hand """ h = Hand() card1 = Card('two', [2]) card2 = Card('king', [10]) h.add_card(card1) h.add_card(card2) self.assertListEqual(list(h.get_possible_scores()), [12]) self.assertListEqual(list(h.get_cards()), [card1, card2]) expected_tree = BinaryTree( BinaryTreeNode(0, BinaryTreeNode(2, BinaryTreeNode(12)))) self.assertTrue(h.hands.is_equivalent(expected_tree))
def test_leaves_just_root(self): """ Tests the leaves returned from a singleton root tree """ bt = BinaryTree(BinaryTreeNode(1)) self.assertListEqual(list(bt.get_leaves()), [bt.root])
import sys, os sys.path.append('./src') from src.BinaryTree import BinaryTree a = BinaryTree() ''' # Test 1. -> Finally works! a.insert(5) a.insert(1) a.insert(7) a.insert(3) a.insert(2) a.insert(4) ''' ''' # Test 2. No need to balance. -> Works! a.insert(5) a.insert(2) a.insert(6) ''' ''' # Test 3. Only left-left rotation needed. -> Works! a.insert(3) a.insert(2) a.insert(1) ''' '''
# -*- coding: utf-8 -*- """ Created on Thu Jul 9 11:03:45 2020 @author: Manish """ from src.BinaryTree import BinaryTree a = BinaryTree() print("TESTING INSERTION") #a.insert_arr([6, 4, 7, 1, 5, 2, 1.5, 3, 4.5, 5.5, 9, 8, 10]) a.insert_arr([6, 4, 7, 1, 5, 2, 1.5, 3, 4.5, 5.5, 9, 11, 10]) a.display_tree(a.rootNode) print() print("TESTING SEARCH") mynode = a.search(10) print(mynode.parent.val) print() print("TESTING DELETION") a.delete(4.5) a.display_tree(a.rootNode) a.delete(9) a.display_tree(a.rootNode) a.delete(6)
class ExpressionBuilder: def __init__(self): self.exp_elements_infix = [] self.exp_elements_suffix = [] self.tree = None self.ans = None def __str__(self): string = "" for element in self.exp_elements_infix: if element == Const.RightBracket: string += ")" elif element == Const.LeftBracket: string += "(" elif element == Const.Plus: string += "+" elif element == Const.Sub: string += "-" elif element == Const.Mul: string += "*" elif element == Const.Div: string += "/" elif element == Const.Pow: string += "**" else: string += str(element) return string @staticmethod def __rand_op_num(): return random.randint(1, 10) @staticmethod def __rand_op(mode): """mode为Easy时, 整数加减乘除; mode为Medium时, 加分数; mode为Hard时, 加乘方""" if mode == Const.Easy or mode == Const.Medium: return random.randint(Const.Plus, Const.Div) if mode == Const.Hard: return random.randint(Const.Plus, Const.Pow) @staticmethod def __rand_num(): return random.randint(0, 100) @staticmethod def __rand_pow_num(): return random.randint(1, 3) def build_exp_infix(self, mode): """ 为了便于生成表达式, 也为了方便计算, 做出以下规定: 1. 一个表达式中最多只有一个乘方运算 2. 除号和幂运算后不生成左括号 3. 乘方幂的范围为1, 2, 3 :param mode: :return: """ op_num = ExpressionBuilder.__rand_op_num() length = 0 left_bracket_num = 0 last_left_bracket = 0 have_pow = False j = 1 while j <= op_num + 1: # 生成一个随机数 self.exp_elements_infix.append(self.__rand_num()) length += 1 # 生成随机数后的处理 if length > 1 and self.exp_elements_infix[length - 2] == Const.Pow: # 乘方运算只能是1, 2, 3 self.exp_elements_infix[length - 1] = self.__rand_pow_num() if length > 1 and self.exp_elements_infix[ length - 2] == Const.Div and self.exp_elements_infix[length - 1] == 0: # 防止除数为0 self.exp_elements_infix[length - 1] = 1 if left_bracket_num > 0 and random.randint( 0, 2) == 0 and last_left_bracket > 2: # 1/3的概率可以添加右括号 self.exp_elements_infix.append(Const.RightBracket) length += 1 left_bracket_num -= 1 last_left_bracket = 0 if j != op_num + 1: # 生成一个随机的符号 self.exp_elements_infix.append(self.__rand_op(mode)) length += 1 # 生成随机符号之后的处理 if have_pow and self.exp_elements_infix[length - 1] == Const.Pow: # 如果刚刚生成的是乘方运算符, 且之前已经有过乘方运算符 self.exp_elements_infix[length - 1] = self.__rand_op( Const.Easy) elif have_pow is False and self.exp_elements_infix[ length - 1] == Const.Pow: have_pow = True # 随机生成左括号 if self.exp_elements_infix[ length - 1] != Const.Pow and self.exp_elements_infix[ length - 1] != Const.Div: # 前一个运算符不是幂运算或乘方 if random.randint(0, 4) == 0 and j != op_num: self.exp_elements_infix.append(Const.LeftBracket) left_bracket_num += 1 length += 1 last_left_bracket = 1 else: while left_bracket_num > 0: self.exp_elements_infix.append(Const.RightBracket) length += 1 left_bracket_num -= 1 if last_left_bracket != 0: last_left_bracket += 1 j += 1 def infix_to_suffix(self): op_stack = Stack() for element in self.exp_elements_infix: if element == Const.Pow or element == Const.LeftBracket: # 左括号和乘方必定入栈 op_stack.push(element) elif element == Const.Mul or element == Const.Div: # 乘除法需要弹出乘方与乘除 while op_stack.size() > 0 and \ (op_stack.peek() == Const.Mul or op_stack.peek() == Const.Div or op_stack.peek() == Const.Pow): op = op_stack.pop() self.exp_elements_suffix.append(op) op_stack.push(element) elif element == Const.Plus or element == Const.Sub: while op_stack.size() > 0 and (op_stack.peek() != Const.LeftBracket): op = op_stack.pop() self.exp_elements_suffix.append(op) op_stack.push(element) elif element == Const.RightBracket: while op_stack.peek() != Const.LeftBracket: op = op_stack.pop() self.exp_elements_suffix.append(op) op_stack.pop() else: self.exp_elements_suffix.append(element) while op_stack.size() > 0: self.exp_elements_suffix.append(op_stack.pop()) def suffix_to_tree(self): node_stack = Stack() op_num = 0 for elm in self.exp_elements_suffix: node = Node() if elm < Const.Min: node.type = Const.NumNode node.num = Num(elm) else: op_num += 1 node.type = Const.OpNode node.right = node_stack.pop() node.left = node_stack.pop() node.op = elm node_stack.push(node) self.tree = BinaryTree(node_stack.pop(), op_num) def get_ans(self): assert isinstance(self.tree, BinaryTree), "表达式树不为BinaryTree" self.ans = self.tree.cal() def build(self, mode): self.build_exp_infix(mode) self.infix_to_suffix() self.suffix_to_tree() self.get_ans() assert isinstance(self.tree, BinaryTree) self.tree.adjust_tree(self.tree.root)