From faa442ccb577bdf25c6633f926abc2dbf0104e0a Mon Sep 17 00:00:00 2001 From: Mari Wahl Date: Sat, 10 Jan 2015 19:20:16 -0500 Subject: [PATCH] last fixes: tree common ancestor --- src/trees/binary_search_tree.py | 21 ++++++++++-- src/trees/binary_tree.py | 45 +++++++------------------ src/trees/binary_tree_generators.py | 51 ++++++++++++++++++++++++++--- src/trees/check_ancestor.py | 45 +++++++++++++++++-------- 4 files changed, 109 insertions(+), 53 deletions(-) diff --git a/src/trees/binary_search_tree.py b/src/trees/binary_search_tree.py index 7fcc738..9f82203 100755 --- a/src/trees/binary_search_tree.py +++ b/src/trees/binary_search_tree.py @@ -54,10 +54,22 @@ class Node(object): print self.item if self.left: - return self.left._printPreorder() + self.left._printPreorder() if self.right: - return self.right._printPreorder() + self.right._printPreorder() + + # Another possibility: use an array (a little bit more expensive): + def _preorder_array(self): + nodes = [] + if self.item: + nodes.append(self.item) + if self.left: + nodes.extend(self.left._preorder_array()) + if self.right: + nodes.extend(self.right._preorder_array()) + return nodes + @@ -80,6 +92,11 @@ class BST(object): if self.root: return self.root._search(value) + def preorder_array(self): + if self.root: + return self.root._preorder_array() + else: + return 'Tree is empty.' if __name__ == '__main__': diff --git a/src/trees/binary_tree.py b/src/trees/binary_tree.py index 3a7e0de..796f1cc 100755 --- a/src/trees/binary_tree.py +++ b/src/trees/binary_tree.py @@ -47,6 +47,14 @@ class Node(object): return not self.right and not self.left + def _preorder(self): + print self.item + if self.left: + self.left._preorder() + if self.right: + self.right._preorder() + + class BT(object): @@ -61,40 +69,14 @@ class BT(object): self.root._add(value) - def printPreorder(self): - current = self.root - nodes, stack = [], [] - while stack or current: - if current: - nodes.append(current.item) # this is what change - stack.append(current) - current = current.left - else: - current = stack.pop() - current = current.right - print nodes - - - def printInorder(self): - current = self.root - nodes, stack = [], [] - while stack or current: - - if current: - stack.append(current) - current = current.left - else: - current = stack.pop() - nodes.append(current.item) # this is what change - current = current.right - print nodes - - def search(self, value): if self.root: return self.root._search(value) + def preorder(self): + if self.root: + return self.root._preorder() if __name__ == '__main__': @@ -111,7 +93,4 @@ if __name__ == '__main__': print print "Printing preorder..." - bt.printPreorder() - - print "Printing Inorder..." - bt.printInorder() \ No newline at end of file + bt.preorder() diff --git a/src/trees/binary_tree_generators.py b/src/trees/binary_tree_generators.py index a6e398e..afafa49 100644 --- a/src/trees/binary_tree_generators.py +++ b/src/trees/binary_tree_generators.py @@ -14,14 +14,22 @@ class Node(object): if not self.value: self.value = new_node elif not self.left: - self.left= new_node + self.left = new_node elif not self. right: self.right = new_node else: self.left = self.left.add(value) - return self # without this, it doesn't add! + def search(self, item): + if self.value == item: + return True + found = False + if (self.left and self.left.search(item)) or \ + (self.right and self.right.search(item)): + found = True + return found + def preorder(self): yield self.value if self.left: @@ -40,7 +48,6 @@ class Node(object): for node in self.right.postorder(): yield node - def inorder(self): yield self.value if self.left: @@ -50,6 +57,14 @@ class Node(object): for node in self.right.inorder(): yield node + # this is the most basic way to write this function + def preorder_simple(self): + print self.value + if self.left: + self.left.preorder_simple() + if self.right: + self.right.preorder_simple() + # Another possibility: use an array (a little bit more expensive): def preorder_array(self): @@ -74,6 +89,12 @@ class BT(object): else: self.root.add(value) + def search(self, item): + if self.root: + return self.root.search(item) + else: + return 'Tree is empty.' + def preorder(self): if self.root: return self.root.preorder() @@ -98,6 +119,11 @@ class BT(object): else: return 'Tree is empty.' + def preorder_simple(self): + if self.root: + return self.root.preorder_simple() + else: + return 'Tree is empty.' if __name__ == '__main__': @@ -106,21 +132,38 @@ if __name__ == '__main__': for i in range(1, 11): tree.add(i) + print 'Searching for node 4' + print tree.search(4) + + print 'Searching for node 1' + print tree.search(1) + + print 'Searching for node 12' + print tree.search(12) + + print 'Pre-order generator...' getree = tree.preorder() for i in range(10): print next(getree) - print + print 'Pre-order array...' print tree.preorder_array() print + print 'Pre-order simple...' + + tree.preorder_simple() + + print + print 'Inorder...' getree = tree.inorder() for i in range(10): print next(getree) print + print 'Postorder...' getree = tree.postorder() for i in range(10): diff --git a/src/trees/check_ancestor.py b/src/trees/check_ancestor.py index 3cbfea8..a318958 100755 --- a/src/trees/check_ancestor.py +++ b/src/trees/check_ancestor.py @@ -4,37 +4,54 @@ __author__ = "bt3" from binary_search_tree import BST, Node -from transversal import inorder - -def find_ancestor(path, low_value, high_value): +def find_ancestor(path, low_item, high_item): while path: - current_value = path[0] + current_item = path[0] - if current_value < low_value: + if current_item < low_item: try: path = path[2:] except: - return current_value + return current_item - elif current_value > high_value: + elif current_item > high_item: try: path = path[1:] except: - return current_value + return current_item + + elif low_item <= current_item <= high_item: + return current_item + + +def find_ancestor2(tree, n1, n2): + if not tree: + return False + + if n1 <= tree.item and n2 >= tree.item or (not tree.left and not tree.right) : + return tree.item + + if tree.left and (n1 < tree.item and n2 < tree.item): + return find_ancestor(tree.left, n1, n2) or tree.item + + if tree.right and (n1 > tree.item and n2 > tree.item): + return find_ancestor(tree.right, n1, n2) or tree.item - elif low_value <= current_value <= high_value: - return current_value if __name__ == '__main__': - - bst = BST() l = [10, 5, 6, 3, 8, 2, 1, 11, 9, 4] for i in l: bst.add(i) - nodes = inorder(bst.root) + nodes = bst.preorder_array() + print 'Original: ', l - print 'Inorder: ', nodes + print 'Preorder: ', nodes + + print 'Method 1: ' print 'Ancestor for 3, 11:', find_ancestor(nodes, 3, 11) + + print 'Method 2: ' + print 'Ancestor for 3, 11: ', find_ancestor2(bst.root, 3, 11)