def test_bt_stress(self): from ch06.tree import BinaryTree bt1 = BinaryTree() N = 31 keys = list(range(N)) for k in keys: bt1.insert(k) self.assertEqual(list(range(k + 1)), list(bt1)) self.assertEqual(list(range(N)), list(bt1)) # remove in order for k in keys: bt1.remove(k) self.assertEqual(list(range(k + 1, N)), list(bt1)) n = 0 for k in keys: bt1.insert(k) n += 1 self.assertEqual(list(range(k + 1)), list(bt1)) self.assertEqual(list(range(N)), list(bt1)) # remove in reverse order for k in reversed(keys): bt1.remove(k)
def test_string_structure(self): from ch06.tree import BinaryTree from ch06.challenge import tree_structure bt1 = BinaryTree() self.assertFalse(99 in bt1) bt1.insert(5) bt1.insert(4) bt1.insert(6) bt1.insert(2) bt1.insert(7) bt1.insert(1) bt1.insert(3) # Prefix representation, with value first, then left and then right self.assertEqual('(5,(4,(2,(1,,),(3,,)),),(6,,(7,,)))', tree_structure(bt1.root))
def test_stress_recreate(self): from ch06.tree import BinaryTree from ch06.challenge import tree_structure, recreate_tree # create all subsets of 1..7 groups = [[1], [2], [3], [4], [5], [6], [7]] for _ in range(6): # Create complete tree with three levels. for group in groups: bt = BinaryTree() for x in [4, 2, 6, 1, 3, 5, 7]: bt.insert(x) for s in group: bt.remove(s) s = tree_structure(bt.root) n = recreate_tree(s, int) # recreate and convert to int bt.root = n # validate all values BUT in set are found for i in range(1, 8): if not i in group: self.assertTrue(i in bt) # expand deletions new_groups = [] for group in groups: for i in range(1, 8): if not i in group: new_groups.append(group + [i]) groups = new_groups
def test_bt(self): from ch06.tree import BinaryTree bt1 = BinaryTree() self.assertTrue(bt1.remove(7) is None) # can work even when empty self.assertTrue(bt1.min() is None) bt1.insert(5) self.assertTrue(5 in bt1) bt1.insert(2) self.assertEqual(5, bt1.root.value) self.assertTrue(2 in bt1) self.assertEqual([2, 5], list(bt1)) bt1.insert(1) self.assertTrue(1 in bt1) self.assertEqual([1, 2, 5], list(bt1))
def test_tree(self): from ch06.tree import BinaryTree bt1 = BinaryTree() for n in [19, 14, 53, 3, 15, 26, 58]: bt1.insert(n) last = -1 while not bt1.is_empty(): m = bt1.min() self.assertTrue(m > last) last = m bt1.remove(m)
def test_count_rotations_avl(self): from ch06.balanced import BinaryTree bt1 = BinaryTree() self.assertTrue(bt1.min() is None) for i in [50, 30, 70, 20, 40, 60, 10, 45]: bt1.insert(i) self.assertEqual(50, bt1.root.value) self.assertEqual(30, bt1.root.left.value) self.assertEqual(20, bt1.root.left.left.value) bt1.insert(5) self.assertEqual(10, bt1.root.left.left.value) # rotate
def test_bt_duplicates(self): from ch06.tree import BinaryTree bt1 = BinaryTree() bt1.insert(5) bt1.insert(5) bt1.insert(4) bt1.insert(5) self.assertEqual([4, 5, 5, 5], list(bt1))
def test_avl_bt4(self): from ch06.symbol import BinaryTree bt1 = BinaryTree() bt1.put(5, 5) self.assertTrue(5 in bt1) bt1.put(1, 1) self.assertEqual(5, bt1.root.key) self.assertTrue(1 in bt1) self.assertEqual([1, 5], [key for key, _ in list(bt1)]) # L-R case bt1.put(3, 3) self.assertEqual(3, bt1.root.key) # rotate! self.assertTrue(1 in bt1) self.assertEqual([1, 3, 5], [key for key, _ in list(bt1)])
def test_copy(self): from ch06.tree import BinaryTree bt1 = BinaryTree() bt1.insert(23) bt1.insert(17) bt1.insert(40) bt1.insert(30) bt2 = bt1.copy() total = 0 for v in bt2: total += v self.assertEqual(110, total)
def test_traversal(self): from ch06.tree import BinaryTree bt1 = BinaryTree() bt1.insert(23) bt1.insert(17) bt1.insert(40) bt1.insert(30) total = 0 for v in bt1: total += v self.assertEqual(110, total)
def test_recreate_tree(self): from ch06.challenge import recreate_tree, tree_structure from ch06.tree import BinaryTree root = recreate_tree('(19,,)') self.assertEqual('19', root.value) root = recreate_tree('(19,3,22)') self.assertEqual('3', root.left.value) self.assertEqual('22', root.right.value) root = recreate_tree('(19,3,(22,21,24))') self.assertEqual('3', root.left.value) self.assertEqual('22', root.right.value) self.assertEqual('21', root.right.left.value) self.assertEqual('24', root.right.right.value) root = recreate_tree('(26,,(29,,)') self.assertEqual('26', root.value) root = recreate_tree('(19,(14,(3,,),(15,,)),(53,(26,,(29,,)),(58,,)))') self.assertEqual('19', root.value) self.assertEqual(8, root.size()) # create and flatten again. bt1 = BinaryTree() bt1.insert(10) bt1.insert(15) bt1.insert(13) bt1.insert(11) s = tree_structure(bt1.root) self.assertEqual('(10,,(15,(13,(11,,),),))', s) n = recreate_tree(s) self.assertEqual(s, tree_structure(n)) bt1 = BinaryTree() bt1.insert(12) bt1.insert(5) s = tree_structure(bt1.root) self.assertEqual('(12,(5,,),)', s) n = recreate_tree(s) self.assertEqual(s, tree_structure(n)) root = recreate_tree('(26,(23,,),)') self.assertEqual('26', root.value) root = recreate_tree('(23,5,(30,29,))') self.assertEqual('23', root.value)
def test_symbol_stress(self): from ch06.symbol import BinaryTree sy1 = BinaryTree() N = 127 keys = list(range(N)) for k in keys: sy1.put(k, k + 1) self.assertEqual(k + 1, sy1.root.size()) self.assertEqual(list(range(k + 1)), [key for key, _ in list(sy1)]) check_avl_property(sy1.root) sy1.put(k, k + 2) self.assertEqual(list(range(N)), [key for key, _ in list(sy1)]) # remove keys count = sy1.root.size() for k in keys: sy1.remove(k) count -= 1 if sy1.root: check_avl_property(sy1.root) self.assertEqual(count, sy1.root.size()) self.assertEqual(list(range(k + 1, N)), [key for key, _ in list(sy1)]) for k in keys: sy1.put(k, k + 3) self.assertEqual(list(range(k + 1)), [key for key, _ in list(sy1)]) self.assertEqual(list(range(N)), [key for key, _ in list(sy1)]) # remove in random order random.shuffle(keys) count = sy1.root.size() for k in keys: sy1.remove(k) count -= 1 if sy1.root: check_avl_property(sy1.root) self.assertEqual(count, sy1.root.size())
def test_avl_stress(self): from ch06.balanced import BinaryTree bt1 = BinaryTree() N = 63 keys = list(range(N)) for k in keys: bt1.insert(k) self.assertEqual(list(range(k + 1)), list(bt1)) check_avl_property(bt1.root) self.assertEqual(list(range(N)), list(bt1)) # remove in order for k in keys: bt1.remove(k) self.assertEqual(list(range(k + 1, N)), list(bt1)) check_avl_property(bt1.root) for k in keys: bt1.insert(k) check_avl_property(bt1.root) self.assertEqual(list(range(k + 1)), list(bt1)) self.assertEqual(list(range(N)), list(bt1)) # remove in reverse order for k in reversed(keys): bt1.remove(k) check_avl_property(bt1.root) self.assertEqual(list(range(k)), list(bt1)) for k in keys: bt1.insert(k) check_avl_property(bt1.root) self.assertEqual(list(range(k + 1)), list(bt1)) self.assertEqual(list(range(N)), list(bt1)) # remove in random order. This revealed subtle defect in _remove_min() shuffled = list(keys) random.shuffle(shuffled) for k in shuffled: bt1.remove(k) check_avl_property(bt1.root) self.assertTrue(bt1.is_empty())
def test_val_height_valid_on_remove(self): from ch06.balanced import BinaryTree bt1 = BinaryTree() bt1.insert(7) self.assertEqual(7, bt1.min()) bt1.insert(4) bt1.insert(10) bt1.insert(8) self.assertEqual(2, bt1.root.height) self.assertEqual(4, bt1.root.size()) check_avl_property(bt1.root) bt1.remove(7) self.assertEqual(3, bt1.root.size()) self.assertEqual(1, bt1.root.height) check_avl_property(bt1.root) self.assertEqual(4, bt1.min()) self.assertTrue(4 in bt1) self.assertTrue(10 in bt1) self.assertTrue(8 in bt1) self.assertFalse(7 in bt1)
def test_avl_bt(self): from ch06.symbol import BinaryTree bt1 = BinaryTree() with self.assertRaises(ValueError): bt1.put(None, 99) self.assertTrue(bt1.remove(None) is None) # harmless self.assertTrue(bt1.is_empty()) bt1.put(5, 5) self.assertFalse(bt1.is_empty()) self.assertEqual('5 -> 5 [0]', str(bt1.root)) self.assertTrue(5 in bt1) bt1.put(3, 3) self.assertEqual(5, bt1.root.key) self.assertTrue(3 in bt1) self.assertEqual([3, 5], [key for key, _ in list(bt1)]) # L-L case bt1.put(1, 1) self.assertEqual(3, bt1.root.key) # rotate! self.assertTrue(1 in bt1) self.assertEqual([1, 3, 5], [key for key, _ in list(bt1)]) self.assertTrue(bt1.get(9999) is None) # not present
def test_bt_remove(self): from ch06.tree import BinaryTree # delete with left child having right child bt1 = BinaryTree() bt1.insert(5) bt1.insert(2) bt1.insert(4) bt1.insert(7) self.assertEqual([2, 4, 5, 7], list(bt1)) bt1.remove(5) self.assertEqual([2, 4, 7], list(bt1)) # delete with left child having only left child bt2 = BinaryTree() bt2.insert(5) bt2.insert(2) bt2.insert(1) bt2.insert(7) bt2.insert(8) self.assertEqual([1, 2, 5, 7, 8], list(bt2)) bt2.remove(5) self.assertEqual([1, 2, 7, 8], list(bt2)) # delete with no left child bt3 = BinaryTree() bt3.insert(5) bt3.insert(7) bt3.insert(8) self.assertEqual([5, 7, 8], list(bt3)) bt3.remove(5) self.assertEqual([7, 8], list(bt3)) # delete with no children bt4 = BinaryTree() bt4.insert(5) self.assertEqual([5], list(bt4)) bt4.remove(5) self.assertEqual([], list(bt4))