Skip to content

Commit

Permalink
better binary search trees
Browse files Browse the repository at this point in the history
  • Loading branch information
DavidLeoni committed Dec 19, 2019
1 parent f96101a commit 4db5031
Show file tree
Hide file tree
Showing 4 changed files with 417 additions and 75 deletions.
63 changes: 63 additions & 0 deletions exercises/trees/bin_tree_solution.py
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,23 @@ def fun_rec(self):
return ret
#/jupman-raise

def bin_search_rec(self, m):
""" Assuming the tree is a binary search tree of integer numbers,
RETURN True if m is present in the tree, False otherwise
- MUST EXECUTE IN O(height(t))
- NOTE: with big trees a recursive solution would surely
exceed the call stack, but here we don't mind
"""
#jupman-raise
if m == self.data():
return True
elif m < self.data():
return self.left() != None and self.left().bin_search_rec(m)
else:
return self.right() != None and self.right().bin_search_rec(m)
#/jupman-raise

def bin_insert_rec(self, m):
""" Assuming the tree is a binary search tree of integer numbers,
MODIFIES the tree by inserting a new node with the value m
Expand All @@ -233,6 +250,52 @@ def bin_insert_rec(self, m):
self.right().bin_insert_rec(m)
#/jupman-raise

def univalued_rec(self):
""" RETURN True if the tree is univalued, otherwise RETURN False.
- a tree is univalued when all nodes have the same value as data
- MUST execute in O(n) where n is the number of nodes of the tree
- NOTE: with big trees a recursive solution would surely
exceed the call stack, but here we don't mind
"""
#jupman-raise
if self.left() != None:
if self.left().data() != self.data() or not self.left().univalued_rec():
return False
if self.right() != None:
if self.right().data() != self.data() or not self.right().univalued_rec():
return False

return True
#/jupman-raise

def same_rec(self, other):
""" RETURN True if this binary tree is equal to other binary tree,
otherwise return False.
- MUST execute in O(n) where n is the number of nodes of the tree
- NOTE: with big trees a recursive solution would surely
exceed the call stack, but here we don't mind
- HINT: defining a helper function
def helper(t1, t2):
which recursively calls itself and assumes both of the
inputs can be None may reduce the number of ifs to write.
"""
#jupman-raise
def helper(t1, t2):
if (t1 == None) != (t2 == None): # XOR
return False
if t1 == None and t2 == None:
return True
if t1.data() != t2.data():
return False
return helper(t1.left(), t2.left()) and helper(t1.right(), t2.right())

return helper(self, other)
#/jupman-raise

def sum_stack(self):
""" Supposing the tree holds integer numbers in all nodes,
RETURN the sum of the numbers.
Expand Down
134 changes: 134 additions & 0 deletions exercises/trees/bin_tree_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -741,6 +741,140 @@ def test_09_complex(self):
bt('i')))
self.assertEqual(t.join_rec(),'abcdefghi')

class BinSearchTest(BinaryTreeTest):
def test_complex(self):
t = bt(7,
bt(3,
bt(2),
bt(6)),
bt(12,
bt(8,
None,
bt(11,
bt(9))),
bt(14,
bt(13))))


self.assertTrue(t.bin_search_rec(8))
self.assertTrue(t.bin_search_rec(13))
self.assertTrue(t.bin_search_rec(7))
self.assertFalse(t.bin_search_rec(1))
self.assertFalse(t.bin_search_rec(5))
self.assertFalse(t.bin_search_rec(10))

class BinInsertRecTest(BinaryTreeTest):
def test_complex(self):

t1 = bt(7)
t1.bin_insert_rec(3)
t1.bin_insert_rec(6)
t1.bin_insert_rec(2)
t1.bin_insert_rec(12)
t1.bin_insert_rec(14)
t1.bin_insert_rec(13)
t1.bin_insert_rec(8)
t1.bin_insert_rec(11)
t1.bin_insert_rec(9)

t2 = bt(7,
bt(3,
bt(2),
bt(6)),
bt(12,
bt(8,
None,
bt(11,
bt(9))),
bt(14,
bt(13))))


self.assertTreeEqual(t1, t2)

class UnivaluedRecTest(BinaryTreeTest):

def test_complex_1(self):
t = bt(3,
bt(3,
bt(7),
bt(3)),
bt(3,
bt(2,
None,
bt(3,
bt(3))),
bt(4,
bt(3))))

self.assertFalse(t.univalued_rec())

def test_complex_2(self):
t = bt(3,
bt(3,
bt(3),
bt(3)),
bt(3,
bt(3,
None,
bt(3,
bt(3))),
bt(3,
bt(3))))

self.assertTrue(t.univalued_rec())


class SameRecTest(BinaryTreeTest):

def test_complex_1(self):
t1 = bt(3,
bt(3,
bt(7),
bt(3)),
bt(3,
bt(2,
None,
bt(3,
bt(3))),
bt(4,
bt(3))))
t2 = bt(4,
bt(3,
bt(8),
bt(3)),
bt(3,
bt(4,
bt(3))))

self.assertFalse(t1.same_rec(t2))

def test_complex_2(self):
t1 = bt(3,
bt(3,
bt(7),
bt(3)),
bt(3,
bt(2,
None,
bt(3,
bt(3))),
bt(4,
bt(3))))
t2 = bt(3,
bt(3,
bt(7),
bt(3)),
bt(3,
bt(2,
None,
bt(3,
bt(3))),
bt(4,
bt(3))))

self.assertTrue(t1.same_rec(t2))


class FunRecTest(BinaryTreeTest):

Expand Down

0 comments on commit 4db5031

Please sign in to comment.