From bfc05b8ea3b7c6449c591e699a3b570e9234cc72 Mon Sep 17 00:00:00 2001 From: Philip Salqvist Date: Fri, 4 Mar 2022 11:52:18 +0100 Subject: [PATCH 1/2] Add `validate_bst` function for testing purposes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Also noticed that `bst.py` contained unit tests. Move to `tests` folder, and add test for `ìnsert` function. fixes #844 --- algorithms/tree/bst/bst.py | 41 ----------------------- algorithms/tree/bst/validate_bst.py | 19 +++++++++++ tests/test_tree.py | 51 +++++++++++++++++++++++++++-- 3 files changed, 67 insertions(+), 44 deletions(-) create mode 100644 algorithms/tree/bst/validate_bst.py diff --git a/algorithms/tree/bst/bst.py b/algorithms/tree/bst/bst.py index de1bddd8c..1112d5153 100644 --- a/algorithms/tree/bst/bst.py +++ b/algorithms/tree/bst/bst.py @@ -6,8 +6,6 @@ 4. Traversal (Preorder, Inorder, Postorder) """ -import unittest - class Node(object): def __init__(self, data): self.data = data @@ -98,42 +96,3 @@ def postorder(self, root): self.postorder(root.left) self.postorder(root.right) print(str(root.data), end = ' ') - -""" - The tree is created for testing: - - 10 - / \ - 6 15 - / \ / \ - 4 9 12 24 - / / \ - 7 20 30 - / - 18 -""" - -class TestSuite(unittest.TestCase): - def setUp(self): - self.tree = BST() - self.tree.insert(10) - self.tree.insert(15) - self.tree.insert(6) - self.tree.insert(4) - self.tree.insert(9) - self.tree.insert(12) - self.tree.insert(24) - self.tree.insert(7) - self.tree.insert(20) - self.tree.insert(30) - self.tree.insert(18) - - def test_search(self): - self.assertTrue(self.tree.search(24)) - self.assertFalse(self.tree.search(50)) - - def test_size(self): - self.assertEqual(11, self.tree.size()) - -if __name__ == '__main__': - unittest.main() diff --git a/algorithms/tree/bst/validate_bst.py b/algorithms/tree/bst/validate_bst.py new file mode 100644 index 000000000..88ee11721 --- /dev/null +++ b/algorithms/tree/bst/validate_bst.py @@ -0,0 +1,19 @@ +import math + +def validate_bst(root): + """ Visits node through inorder dfs, and validates that the tree is a BST + :type root: Node + :rtype: bool + """ + def in_order(root, prev): + + if root == None: + return True + if not in_order(root.left, prev): + return False + if root.data <= prev: + return False + prev = root.data + return in_order(root.right, prev) + prev = -math.inf + return in_order(root, prev) diff --git a/tests/test_tree.py b/tests/test_tree.py index 170a931dd..c2908fa1f 100644 --- a/tests/test_tree.py +++ b/tests/test_tree.py @@ -1,3 +1,6 @@ +from algorithms.tree.bst.bst import BST +from algorithms.tree.bst.delete_node import Solution +from algorithms.tree.bst.validate_bst import validate_bst from algorithms.tree.traversal import ( preorder, preorder_rec, @@ -7,11 +10,8 @@ inorder_rec ) from algorithms.tree.b_tree import BTree - from algorithms.tree import construct_tree_postorder_preorder as ctpp - from algorithms.tree.fenwick_tree.fenwick_tree import Fenwick_Tree - import unittest @@ -170,5 +170,50 @@ def test_construct_tree_with_update_3(self): ft.update_bit(bit_tree, 2, 11) self.assertEqual(23, ft.get_sum(bit_tree, 4)) +class TestBST(unittest.TestCase): + + def test_insert(self): + bst = create_bst() + self.assertTrue(validate_bst(bst.root)) + + def test_search(self): + bst = create_bst() + self.assertTrue(bst.search(24)) + self.assertFalse(bst.search(50)) + + def test_size(self): + bst = create_bst() + self.assertEqual(11, bst.size()) + + +def create_bst(): + """ + The following tree is created for testing: + + 10 + / \ + 6 15 + / \ / \ + 4 9 12 24 + / / \ + 7 20 30 + / + 18 + """ + tree = BST() + tree.insert(10) + tree.insert(15) + tree.insert(6) + tree.insert(4) + tree.insert(9) + tree.insert(12) + tree.insert(24) + tree.insert(7) + tree.insert(20) + tree.insert(30) + tree.insert(18) + return tree + + if __name__ == '__main__': unittest.main() From 5fb5928bf7640e4d3246591728bec0f361131db5 Mon Sep 17 00:00:00 2001 From: Philip Salqvist Date: Fri, 4 Mar 2022 15:19:47 +0100 Subject: [PATCH 2/2] Move validate_bst to class BST and update tests accordingly --- algorithms/tree/bst/bst.py | 20 ++++++++++++++++++++ algorithms/tree/bst/validate_bst.py | 19 ------------------- tests/test_tree.py | 16 +++++++++++++--- 3 files changed, 33 insertions(+), 22 deletions(-) delete mode 100644 algorithms/tree/bst/validate_bst.py diff --git a/algorithms/tree/bst/bst.py b/algorithms/tree/bst/bst.py index 1112d5153..706d7d013 100644 --- a/algorithms/tree/bst/bst.py +++ b/algorithms/tree/bst/bst.py @@ -6,6 +6,8 @@ 4. Traversal (Preorder, Inorder, Postorder) """ +import math + class Node(object): def __init__(self, data): self.data = data @@ -96,3 +98,21 @@ def postorder(self, root): self.postorder(root.left) self.postorder(root.right) print(str(root.data), end = ' ') + + def validate_bst(self): + """ Visits node through inorder dfs, and validates that the tree is a BST + :rtype: bool + """ + def in_order(root, prev): + + if root == None: + return True + if not in_order(root.left, prev): + return False + if root.data <= prev: + return False + prev = root.data + return in_order(root.right, prev) + + prev = -math.inf + return in_order(self.root, prev) diff --git a/algorithms/tree/bst/validate_bst.py b/algorithms/tree/bst/validate_bst.py deleted file mode 100644 index 88ee11721..000000000 --- a/algorithms/tree/bst/validate_bst.py +++ /dev/null @@ -1,19 +0,0 @@ -import math - -def validate_bst(root): - """ Visits node through inorder dfs, and validates that the tree is a BST - :type root: Node - :rtype: bool - """ - def in_order(root, prev): - - if root == None: - return True - if not in_order(root.left, prev): - return False - if root.data <= prev: - return False - prev = root.data - return in_order(root.right, prev) - prev = -math.inf - return in_order(root, prev) diff --git a/tests/test_tree.py b/tests/test_tree.py index cd1cff8fc..ceb16e9e3 100644 --- a/tests/test_tree.py +++ b/tests/test_tree.py @@ -1,6 +1,4 @@ from algorithms.tree.bst.bst import BST -from algorithms.tree.bst.delete_node import Solution -from algorithms.tree.bst.validate_bst import validate_bst from algorithms.tree.traversal import ( preorder, preorder_rec, @@ -176,17 +174,29 @@ def test_construct_tree_with_update_3(self): self.assertEqual(23, ft.get_sum(bit_tree, 4)) class TestBST(unittest.TestCase): + """ + Testing binary search tree functionality + """ def test_insert(self): + """ + Testing that bst structure is valid after insert + """ bst = create_bst() - self.assertTrue(validate_bst(bst.root)) + self.assertTrue(bst.validate_bst()) def test_search(self): + """ + Testing search functionality + """ bst = create_bst() self.assertTrue(bst.search(24)) self.assertFalse(bst.search(50)) def test_size(self): + """ + Testing size function + """ bst = create_bst() self.assertEqual(11, bst.size())