From 5a7a97b25fab098a25fc4a6a89c9afbe4be1f784 Mon Sep 17 00:00:00 2001 From: Mari Wahl Date: Wed, 27 Aug 2014 18:53:46 -0400 Subject: [PATCH] fix few details, stacks --- .../trees/binary_trees => trees/BST}/BST.py | 0 .../BST}/BST_with_Nodes.py | 0 .../trees/binary_trees => trees/BST}/BT.py | 0 .../binary_trees => trees/BST}/BT_lists.py | 0 .../trees => trees/BST}/__init__.py | 0 .../trees/binary_trees => trees/BST}/avl.py | 0 .../BST}/binary_search_tree.py | 0 .../BST}/veritfy_if_BST.py | 0 .../trees/binary_trees => trees}/__init__.py | 0 .../binary_trees_and_others}/__init__.py | 0 .../binary_trees_and_others/binary_tree.py | 173 +++++++++++++ .../binary_tree_lists.py | 64 +++++ .../binary_trees_and_others}/bunchclass.py | 10 +- .../binary_trees_and_others}/tree.py | 16 +- .../trees/traversals/BST.py | 0 .../trees/traversals/BST_ancestor.py | 0 .../trees/traversals/BST_traversal.py | 0 .../traversals/BST_with_Nodes_traversal.py | 0 .../traversals/BST_with_extra_methods.py | 0 .../trees/traversals/__init__.py | 0 .../traversals}/binary_tree.py | 234 +++++++++--------- .../traversals}/traversals.py | 0 22 files changed, 369 insertions(+), 128 deletions(-) rename src/{graphs_and_trees/trees/binary_trees => trees/BST}/BST.py (100%) rename src/{graphs_and_trees/trees/binary_trees => trees/BST}/BST_with_Nodes.py (100%) rename src/{graphs_and_trees/trees/binary_trees => trees/BST}/BT.py (100%) rename src/{graphs_and_trees/trees/binary_trees => trees/BST}/BT_lists.py (100%) rename src/{graphs_and_trees/trees => trees/BST}/__init__.py (100%) rename src/{graphs_and_trees/trees/binary_trees => trees/BST}/avl.py (100%) rename src/{graphs_and_trees/trees_basics => trees/BST}/binary_search_tree.py (100%) rename src/{graphs_and_trees/trees/binary_trees => trees/BST}/veritfy_if_BST.py (100%) rename src/{graphs_and_trees/trees/binary_trees => trees}/__init__.py (100%) rename src/{graphs_and_trees/trees/simple_trees => trees/binary_trees_and_others}/__init__.py (100%) create mode 100644 src/trees/binary_trees_and_others/binary_tree.py create mode 100644 src/trees/binary_trees_and_others/binary_tree_lists.py rename src/{graphs_and_trees/trees/simple_trees => trees/binary_trees_and_others}/bunchclass.py (85%) rename src/{graphs_and_trees/trees/simple_trees => trees/binary_trees_and_others}/tree.py (66%) rename src/{graphs_and_trees => }/trees/traversals/BST.py (100%) rename src/{graphs_and_trees => }/trees/traversals/BST_ancestor.py (100%) rename src/{graphs_and_trees => }/trees/traversals/BST_traversal.py (100%) rename src/{graphs_and_trees => }/trees/traversals/BST_with_Nodes_traversal.py (100%) rename src/{graphs_and_trees => }/trees/traversals/BST_with_extra_methods.py (100%) rename src/{graphs_and_trees => }/trees/traversals/__init__.py (100%) rename src/{graphs_and_trees/trees_basics => trees/traversals}/binary_tree.py (80%) rename src/{graphs_and_trees/trees_basics => trees/traversals}/traversals.py (100%) diff --git a/src/graphs_and_trees/trees/binary_trees/BST.py b/src/trees/BST/BST.py similarity index 100% rename from src/graphs_and_trees/trees/binary_trees/BST.py rename to src/trees/BST/BST.py diff --git a/src/graphs_and_trees/trees/binary_trees/BST_with_Nodes.py b/src/trees/BST/BST_with_Nodes.py similarity index 100% rename from src/graphs_and_trees/trees/binary_trees/BST_with_Nodes.py rename to src/trees/BST/BST_with_Nodes.py diff --git a/src/graphs_and_trees/trees/binary_trees/BT.py b/src/trees/BST/BT.py similarity index 100% rename from src/graphs_and_trees/trees/binary_trees/BT.py rename to src/trees/BST/BT.py diff --git a/src/graphs_and_trees/trees/binary_trees/BT_lists.py b/src/trees/BST/BT_lists.py similarity index 100% rename from src/graphs_and_trees/trees/binary_trees/BT_lists.py rename to src/trees/BST/BT_lists.py diff --git a/src/graphs_and_trees/trees/__init__.py b/src/trees/BST/__init__.py similarity index 100% rename from src/graphs_and_trees/trees/__init__.py rename to src/trees/BST/__init__.py diff --git a/src/graphs_and_trees/trees/binary_trees/avl.py b/src/trees/BST/avl.py similarity index 100% rename from src/graphs_and_trees/trees/binary_trees/avl.py rename to src/trees/BST/avl.py diff --git a/src/graphs_and_trees/trees_basics/binary_search_tree.py b/src/trees/BST/binary_search_tree.py similarity index 100% rename from src/graphs_and_trees/trees_basics/binary_search_tree.py rename to src/trees/BST/binary_search_tree.py diff --git a/src/graphs_and_trees/trees/binary_trees/veritfy_if_BST.py b/src/trees/BST/veritfy_if_BST.py similarity index 100% rename from src/graphs_and_trees/trees/binary_trees/veritfy_if_BST.py rename to src/trees/BST/veritfy_if_BST.py diff --git a/src/graphs_and_trees/trees/binary_trees/__init__.py b/src/trees/__init__.py similarity index 100% rename from src/graphs_and_trees/trees/binary_trees/__init__.py rename to src/trees/__init__.py diff --git a/src/graphs_and_trees/trees/simple_trees/__init__.py b/src/trees/binary_trees_and_others/__init__.py similarity index 100% rename from src/graphs_and_trees/trees/simple_trees/__init__.py rename to src/trees/binary_trees_and_others/__init__.py diff --git a/src/trees/binary_trees_and_others/binary_tree.py b/src/trees/binary_trees_and_others/binary_tree.py new file mode 100644 index 0000000..d8cd56f --- /dev/null +++ b/src/trees/binary_trees_and_others/binary_tree.py @@ -0,0 +1,173 @@ +#!/usr/bin/python + +__author__ = "Mari Wahl" +__email__ = "marina.w4hl@gmail.com" + + + +''' Implementation of a binary tree and its properties. For example, the following bt: + + 1 ---> level 0 + 2 3 ---> level 1 + 4 5 ---> level 2 + 6 7 ---> level 3 + 8 9 ---> level 4 + + has the following properties: + + - SIZE OR NUMBER OF NODES: n = 9 + - NUMBER OF BRANCHES OR INTERNAL NODES: b = n-1 = 8 + - VALUE OF ROOT = 1 + - MAX_DEPTH OR HEIGHT: h = 4 + - IS BALANCED? NO + - IS BST? NO +''' + + +class NodeBT(object): + def __init__(self, item=None, level=0): + self.item = item + self.level = level + self.left = None + self.right = None + + + def __repr__(self): + return '{}'.format(self.item) + + + def _addNextNode(self, value, level_here=1): + new_node = NodeBT(value, level_here) + if not self.item: + self.item = new_node + elif not self.left: + self.left = new_node + elif not self.right: + self.right = new_node + else: + self.left = self.left._addNextNode(value, level_here+1) + return self + + + def _searchForNode(self, value): + if self.item == value: + return self + else: + found = None + if self.left: + found = self.left._searchForNode(value) + if self.right: + found = found or self.right._searchForNode(value) + return found + + + def _isLeaf(self): + return not self.right and not self.left + + + def _getMaxHeight(self): + ''' Get the max height at the node, O(n)''' + levelr, levell = 0, 0 + if self.right: + levelr = self.right._getMaxHeight() + 1 + if self.left: + levell = self.left._getMaxHeight() + 1 + return max(levelr, levell) + + + def _getMinHeight(self, level=0): + ''' Get the min height at the node, O(n)''' + levelr, levell = -1, -1 + if self.right: + levelr = self.right._getMinHeight(level +1) + if self.left: + levell = self.left._getMinHeight(level +1) + return min(levelr, levell) + 1 + + + def _isBalanced(self): + ''' Find whether the tree is balanced, by calculating heights first, O(n2) ''' + if self._getMaxHeight() - self._getMinHeight() < 2: + return False + else: + if self._isLeaf(): + return True + elif self.left and self.right: + return self.left._isBalanced() and self.right._isBalanced() + elif not self.left and self.right: + return self.right._isBalanced() + elif not self.right and self.left: + return self.left._isBalanced() + + def _isBST(self): + ''' Find whether the tree is a BST, inorder ''' + if self.item: + if self._isLeaf(): + return True + elif self.left: + if self.left.item < self.item: + return self.left._isBST() + else: + return False + elif self.right: + if self.right.item > self.item: + return self.right._isBST() + else: + return False + else: + raise Exception('Tree is empty') + + + + + +class BinaryTree(object): + + def __init__(self): + self.root = None + + + def addNode(self, value): + if not self.root: + self.root = NodeBT(value) + else: + self.root._addNextNode(value) + + + def isLeaf(self, value): + node = self.root._searchForNode(value) + return node._isLeaf() + + def getNodeLevel(self, item): + node = self.root._searchForNode(item) + if node: + return node.level + else: + raise Exception('Node not found') + + def isRoot(self, value): + return self.root.item == value + + def getHeight(self): + return self.root._getMaxHeight() + + def isBalanced(self): + return self.root._isBalanced() + + def isBST(self): + return self.root._isBST() + + + +if __name__ == '__main__': + bt = BinaryTree() + print "Adding nodes 1 to 10 in the tree..." + for i in range(1, 10): + bt.addNode(i) + print "Is 8 a leaf? ", bt.isLeaf(8) + print "Whats the level of node 8? ", bt.getNodeLevel(8) + print "Is node 10 a root? ", bt.isRoot(10) + print "Is node 1 a root? ", bt.isRoot(1) + print "Whats the tree height? ", bt.getHeight() + print "Is this tree BST? ", bt.isBST() + print "Is this tree balanced? ", bt.isBalanced() \ No newline at end of file diff --git a/src/trees/binary_trees_and_others/binary_tree_lists.py b/src/trees/binary_trees_and_others/binary_tree_lists.py new file mode 100644 index 0000000..966cb33 --- /dev/null +++ b/src/trees/binary_trees_and_others/binary_tree_lists.py @@ -0,0 +1,64 @@ +#!/usr/bin/python + +__author__ = "Mari Wahl" +__email__ = "marina.w4hl@gmail.com" + + +''' constructs a list with a root and 2 empty sublists for the children. To add a left subtree to the root of a tree, we need to insert a new list into the second position of the root list ''' + + +def BinaryTreeList(r): + return [r, [], []] + + +def insertLeft(root, newBranch): + t = root.pop(1) + if len(t) > 1: + root.insert(1,[newBranch,t,[]]) + else: + root.insert(1,[newBranch, [], []]) + return root + + +def insertRight(root, newBranch): + t = root.pop(2) + if len(t) > 1: + root.insert(2,[newBranch,[],t]) + else: + root.insert(2,[newBranch,[],[]]) + return root + +def getRootVal(root): + return root[0] + +def setRootVal(root, newVal): + root[0] = newVal + +def getLeftChild(root): + return root[1] + +def getRightChild(root): + return root[2] + + + +def main(): + ''' + 3 + [5, [4, [], []], []] + [7, [], [6, [], []]] + ''' + + r = BinaryTreeList(3) + insertLeft(r,4) + insertLeft(r,5) + insertRight(r,6) + insertRight(r,7) + print(getRootVal(r)) + print(getLeftChild(r)) + print(getRightChild(r)) + + +if __name__ == '__main__': + main() + diff --git a/src/graphs_and_trees/trees/simple_trees/bunchclass.py b/src/trees/binary_trees_and_others/bunchclass.py similarity index 85% rename from src/graphs_and_trees/trees/simple_trees/bunchclass.py rename to src/trees/binary_trees_and_others/bunchclass.py index 03b3104..c7a7748 100644 --- a/src/graphs_and_trees/trees/simple_trees/bunchclass.py +++ b/src/trees/binary_trees_and_others/bunchclass.py @@ -1,13 +1,13 @@ -#!/usr/bin/python3 -# mari von steinkirch @2013 -# steinkirch at gmail +#!/usr/bin/python +__author__ = "Mari Wahl" +__email__ = "marina.w4hl@gmail.com" class BunchClass(dict): def __init__(self, *args, **kwds): super(BunchClass, self).__init__(*args, **kwds) self.__dict__ = self - + def main(): ''' {'right': {'right': 'Xander', 'left': 'Willow'}, 'left': {'right': 'Angel', 'left': 'Buffy'}}''' @@ -20,4 +20,4 @@ if __name__ == '__main__': - + diff --git a/src/graphs_and_trees/trees/simple_trees/tree.py b/src/trees/binary_trees_and_others/tree.py similarity index 66% rename from src/graphs_and_trees/trees/simple_trees/tree.py rename to src/trees/binary_trees_and_others/tree.py index e0646a7..5bd02f4 100644 --- a/src/graphs_and_trees/trees/simple_trees/tree.py +++ b/src/trees/binary_trees_and_others/tree.py @@ -1,13 +1,16 @@ -#!/usr/bin/python3 -# mari von steinkirch @2013 -# steinkirch at gmail +#!/usr/bin/python +__author__ = "Mari Wahl" +__email__ = "marina.w4hl@gmail.com" + +""" A class for a simple tree """ class SimpleTree(object): - def __init__(self, value, children = None): - if children == None: children = [] + def __init__(self, value=None, children = None): + self.value = value self.children = children - self.value = value + if self.children == None: + self.children = [] def __repr__(self, level=0): ret = "\t"*level+repr(self.value)+"\n" @@ -16,6 +19,7 @@ class SimpleTree(object): return ret + def main(): """ 'a' diff --git a/src/graphs_and_trees/trees/traversals/BST.py b/src/trees/traversals/BST.py similarity index 100% rename from src/graphs_and_trees/trees/traversals/BST.py rename to src/trees/traversals/BST.py diff --git a/src/graphs_and_trees/trees/traversals/BST_ancestor.py b/src/trees/traversals/BST_ancestor.py similarity index 100% rename from src/graphs_and_trees/trees/traversals/BST_ancestor.py rename to src/trees/traversals/BST_ancestor.py diff --git a/src/graphs_and_trees/trees/traversals/BST_traversal.py b/src/trees/traversals/BST_traversal.py similarity index 100% rename from src/graphs_and_trees/trees/traversals/BST_traversal.py rename to src/trees/traversals/BST_traversal.py diff --git a/src/graphs_and_trees/trees/traversals/BST_with_Nodes_traversal.py b/src/trees/traversals/BST_with_Nodes_traversal.py similarity index 100% rename from src/graphs_and_trees/trees/traversals/BST_with_Nodes_traversal.py rename to src/trees/traversals/BST_with_Nodes_traversal.py diff --git a/src/graphs_and_trees/trees/traversals/BST_with_extra_methods.py b/src/trees/traversals/BST_with_extra_methods.py similarity index 100% rename from src/graphs_and_trees/trees/traversals/BST_with_extra_methods.py rename to src/trees/traversals/BST_with_extra_methods.py diff --git a/src/graphs_and_trees/trees/traversals/__init__.py b/src/trees/traversals/__init__.py similarity index 100% rename from src/graphs_and_trees/trees/traversals/__init__.py rename to src/trees/traversals/__init__.py diff --git a/src/graphs_and_trees/trees_basics/binary_tree.py b/src/trees/traversals/binary_tree.py similarity index 80% rename from src/graphs_and_trees/trees_basics/binary_tree.py rename to src/trees/traversals/binary_tree.py index a33fa1a..253482c 100644 --- a/src/graphs_and_trees/trees_basics/binary_tree.py +++ b/src/trees/traversals/binary_tree.py @@ -1,20 +1,20 @@ -#!/usr/bin/python3 -# mari von steinkirch 2013 -# http://astro.sunysb.edu/steinkirch +#!/usr/bin/python + +__author__ = "Mari Wahl" +__email__ = "marina.w4hl@gmail.com" +''' Implementation of a binary tree and its properties. For example, the following bt: -''' Implementation of a binary tree and its properties. For example, the following bt: - 1 ---> level 0 2 3 ---> level 1 4 5 ---> level 2 6 7 ---> level 3 - 8 9 ---> level 4 - + 8 9 ---> level 4 + has the following properties: - + - SIZE OR NUMBER OF NODES: n = 9 - NUMBER OF BRANCHES OR INTERNAL NODES: b = n-1 = 8 - VALUE OF ROOT = 1 @@ -35,13 +35,13 @@ class NodeBT(object): self.level = level self.left = None self.right = None - self.traversal = [] + self.traversal = [] #self.parent = None # not used here but can be necessary for some problems - - ''' + + ''' METHODS TO MODIFY NODES - ''' - + ''' + def _addNextNode(self, value, level_here=1): ''' Aux for self.addNode(value)''' self.traversal = [] @@ -53,27 +53,27 @@ class NodeBT(object): elif not self.right: self.right = new_node else: - self.left = self.left._addNextNode(value, level_here+1) - return self - + self.left = self.left._addNextNode(value, level_here+1) + return self + ''' - METHODS TO PRINT/SHOW NODES' ATTRIBUTES - ''' + METHODS TO PRINT/SHOW NODES' ATTRIBUTES + ''' def __repr__(self): ''' Private method for this class'string representation''' - return '{}'.format(self.item) + return '{}'.format(self.item) def _getDFTpreOrder(self, node): ''' Traversal Pre-Order, O(n)''' if node: if node.item: self.traversal.append(node.item) self._getDFTpreOrder(node.left) - self._getDFTpreOrder(node.right) + self._getDFTpreOrder(node.right) return self - + def _printDFTpreOrder(self, noderoot): ''' Fill the pre-order traversal array ''' self.traversal = [] @@ -85,9 +85,9 @@ class NodeBT(object): if node: self._getDFTinOrder(node.left) if node.item: self.traversal.append(node.item) - self._getDFTinOrder(node.right) + self._getDFTinOrder(node.right) return self - + def _printDFTinOrder(self, noderoot): ''' Fill the in-order traversal array ''' self.traversal = [] @@ -98,29 +98,29 @@ class NodeBT(object): ''' Traversal post-Order, O(n)''' if node: self._getDFTpostOrder(node.left) - self._getDFTpostOrder(node.right) + self._getDFTpostOrder(node.right) if node.item: self.traversal.append(node.item) - return self - + return self + def _getBFT(self, node): - ''' Traversal bft, O(n)''' + ''' Traversal bft, O(n)''' if node: - queue = deque() + queue = deque() queue.append(node) while len(queue) > 0: current = queue.popleft() if current.item: self.traversal.append(current) if current.left: queue.append(current.left) - if current.right: queue.append(current.right) - return self + if current.right: queue.append(current.right) + return self def _printBFT(self, noderoot): ''' Fill the in-order traversal array ''' self.traversal = [] self._getBFT(noderoot) return self.traversal - - + + def _printDFTpostOrder(self, noderoot): ''' Fill the post-order traversal array ''' self.traversal = [] @@ -132,14 +132,14 @@ class NodeBT(object): if self.item == value: return self else: found = None - if self.left: found = self.left._searchForNode(value) - if self.right: found = found or self.right._searchForNode(value) + if self.left: found = self.left._searchForNode(value) + if self.right: found = found or self.right._searchForNode(value) return found def _findNode(self, value): ''' Find whether a node is in the tree. if the traversal was calculated, it is just a membership - checking, which is O(1), otherwise it is necessary to traverse + checking, which is O(1), otherwise it is necessary to traverse the binary tree, so best case is O(1) and worst is O(n). ''' if self.traversal: return value in self.traversal else: return self._searchForNode(value) @@ -154,8 +154,8 @@ class NodeBT(object): if self.right: levelr = self.right._getMaxHeight() + 1 if self.left: - levell = self.left._getMaxHeight() + 1 - return max(levelr, levell) + levell = self.left._getMaxHeight() + 1 + return max(levelr, levell) def _getMinHeight(self, level=0): ''' Get the min height at the node, O(n)''' @@ -163,9 +163,9 @@ class NodeBT(object): if self.right: levelr = self.right._getMinHeight(level +1) if self.left: - levell = self.left._getMinHeight(level +1) - return min(levelr, levell) + 1 - + levell = self.left._getMinHeight(level +1) + return min(levelr, levell) + 1 + def _isBalanced(self): ''' Find whether the tree is balanced, by calculating heights first, O(n2) ''' if self._getMaxHeight() - self._getMinHeight() < 2: @@ -174,14 +174,14 @@ class NodeBT(object): if self._isLeaf(): return True elif self.left and self.right: - return self.left._isBalanced() and self.right._isBalanced() + return self.left._isBalanced() and self.right._isBalanced() elif not self.left and self.right: - return self.right._isBalanced() + return self.right._isBalanced() elif not self.right and self.left: - return self.right._isBalanced() + return self.right._isBalanced() + - def _isBalancedImproved(self): ''' Find whehter the tree is balanced in each node, O(n) ''' return 'To Be written' @@ -190,37 +190,37 @@ class NodeBT(object): (1) Do an inorder, check if the inorder is sorted. However inorder can't handle the difference between duplicate values on the left or on the right (if it is in the right, the tree is not bst). - ''' + ''' def _isBST(self): ''' Find whether the tree is a BST, inorder ''' if self.item: - if self._isLeaf(): return True + if self._isLeaf(): return True elif self.left: - if self.left.item < self.item: return self.left._isBST() + if self.left.item < self.item: return self.left._isBST() else: return False elif self.right: if self.right.item > self.item: return self.right._isBST() else: return False else: raise Exception('Tree is empty') - + def _getAncestorBST(self, n1, n2): ''' Return the ancestor of two nodes if it is a bst. we are supposing the values in the tree are unique.''' - if n1 == self.item or n2 == self.item : return self.item + if n1 == self.item or n2 == self.item : return self.item elif self.item < n1 and self.item < n2: self.right.getAncestorBST(n1, n2) elif self.item > n1 and self.item > n2: self.left.getAncestorBST(n1, n2) else: - return self.item + return self.item + + + - - - class BinaryTree(object): ''' >>> bt = BinaryTree() @@ -270,30 +270,30 @@ class BinaryTree(object): >>> bt.getAncestor(8, 5, 'post-in') 2 ''' - - - - def __init__(self): - ''' Construtor for the Binary Tree, which is a container of Nodes''' - self.root = None - - ''' + + + def __init__(self): + ''' Constructor for the Binary Tree, which is a container of Nodes''' + self.root = None + + + ''' METHODS TO MODIFY THE TREE - ''' - + ''' + def addNode(self, value): ''' Add new node to the tree, by the left first, O(n) ''' if not self.root: self.root = NodeBT(value) - else: self.root._addNextNode(value) + else: self.root._addNextNode(value) ''' - METHODS TO PRINT/SHOW TREES' ATTRIBUTES - ''' - + METHODS TO PRINT/SHOW TREES' ATTRIBUTES + ''' + def __repr__(self): ''' Private method for this class'string representation''' - return '{}'.format(self.item) + return '{}'.format(self.item) def printTree(self, order = 'pre'): ''' Print Tree in the chosen order ''' @@ -301,53 +301,53 @@ class BinaryTree(object): if order == 'pre': return self.root._printDFTpreOrder(self.root) elif order == 'in': return self.root._printDFTinOrder(self.root) elif order == 'post': return self.root._printDFTpostOrder(self.root) - elif order == 'bft': return self.root._printBFT(self.root) + elif order == 'bft': return self.root._printBFT(self.root) else: raise Exception('Tree is empty') def hasNode(self, value): ''' Verify whether the node is in the Tree ''' - return bool(self.root._findNode(value)) - + return bool(self.root._findNode(value)) + def isLeaf(self, value): ''' Return True if the node is a Leaf ''' node = self.root._searchForNode(value) - return node._isLeaf() - + return node._isLeaf() + def getNodeLevel(self, item): ''' Return the level of the node, best O(1), worst O(n) ''' node = self.root._searchForNode(item) if node: return node.level else: raise Exception('Node not found') - + def getSizeTree(self): - ''' Return how many nodes in the tree, O(n) ''' + ''' Return how many nodes in the tree, O(n) ''' return len(self.root._printDFTpreOrder(self.root)) - + def isRoot(self, value): '''Return the root of the tree ''' return self.root.item == value - + def getHeight(self): ''' Returns the height/depth of the tree, best/worst O(n) ''' return self.root._getMaxHeight() - + def isBalanced(self, method=1): ''' Return True if the tree is balanced''' if method == 1: ''' O(n2)''' - return self.root._isBalanced() + return self.root._isBalanced() else: ''' O(n)''' - return self.root._isBalancedImproved() - + return self.root._isBalancedImproved() - ''' The followin methods are for searching the lowest common ancestor + + ''' The following methods are for searching the lowest common ancestor in a BT. Since a simple BT does not have ordering, it can be O(n). If we have a link for the ancestors, the steps are: (1) search both trees in order to find the nodes separately - (2) list all ancestors - (3) find first that mach + (2) list all ancestors + (3) find first that mach obs: if we do this too many times we can do a pre and use the methods here''' def isBST(self, method=1): @@ -365,12 +365,12 @@ class BinaryTree(object): preorder = preorder[1:] i = 0 item = inorder[0] - value1left, value2left = False, False - while item != root and i < len(inorder): + value1left, value2left = False, False + while item != root and i < len(inorder): if item == value1: value1left = True elif item == value2: value2left = True i += 1 - item = inorder[i] + item = inorder[i] if (value1left and not value2left) or (value2left and not value1left): return root else: @@ -380,44 +380,44 @@ class BinaryTree(object): ''' Return the ancestor of two nodes with pre and post''' root = preorder[0] preorder = preorder[1:] - postorder = postorder[:-1] - value1right, value2right = False, False + postorder = postorder[:-1] + value1right, value2right = False, False i = len(postorder)-1 itempre = preorder[0] - itempos = postorder[i] + itempos = postorder[i] while itempre != itempos and i > 0: if itempos == value1: value1right = True - elif itempos == value2: value2right = True + elif itempos == value2: value2right = True i -= 1 itempos = postorder[i] - + if (value1right and not value2right) or (value2right and not value1right): return root else: - return self._getAncestorPrePost(preorder, postorder[:i] + postorder[i+1:], value1, value2) - + return self._getAncestorPrePost(preorder, postorder[:i] + postorder[i+1:], value1, value2) + def _getAncestorInPost(self, inorder, postorder, value1, value2): ''' Return the ancestor of two nodes with in and post''' root = postorder[-1] - postorder = postorder[:-1] - value1left, value2left = False, False + postorder = postorder[:-1] + value1left, value2left = False, False i = 0 - item = inorder[i] + item = inorder[i] while item != root and i < len(inorder): if item == value1: value1left = True - elif item == value2: value2left = True + elif item == value2: value2left = True i += 1 item = inorder[i] - + if (value1left and not value2left) or (value2left and not value1left): return root else: - return self._getAncestorInPost(postorder, inorder[:i] + inorder[i+1:], value1, value2) - - + return self._getAncestorInPost(postorder, inorder[:i] + inorder[i+1:], value1, value2) + + + + - - def _getAncestorBST2(self, preorder, value1, value2): ''' Return the ancestor of two nodes if it is a bst, using traversal''' while preorder: @@ -430,35 +430,35 @@ class BinaryTree(object): except: return current elif value1 <= current <= value2: return current - return None + return None def getAncestor(self, value1, value2, method='pre-in'): ''' Return the commom ancestor for two nodes''' if method == 'pre-in': - ''' Using pre and inorder, best/worst O(n)''' + ''' Using pre and inorder, best/worst O(n)''' preorder = self.root._printDFTpreOrder(self.root) inorder = self.root._printDFTinOrder(self.root) - return self._getAncestorPreIn(preorder, inorder, value1, value2) + return self._getAncestorPreIn(preorder, inorder, value1, value2) if method == 'pre-post': - ''' Using pre and postorder, best/worst O(n)''' + ''' Using pre and postorder, best/worst O(n)''' preorder = self.root._printDFTpreOrder(self.root) postorder = self.root._printDFTpostOrder(self.root) - return self._getAncestorPrePost(preorder, postorder, value1, value2) + return self._getAncestorPrePost(preorder, postorder, value1, value2) if method == 'post-in': - ''' Using in and postorder, best/worst O(n)''' + ''' Using in and postorder, best/worst O(n)''' inorder = self.root._printDFTinOrder(self.root) postorder = self.root._printDFTpostOrder(self.root) - return self._getAncestorInPost(inorder, postorder, value1, value2) + return self._getAncestorInPost(inorder, postorder, value1, value2) if method == 'bst': if self.isBST(): - return self.root._getAncestorBST(value1, value2) - + return self.root._getAncestorBST(value1, value2) + #preorder = self.root._printDFTpreOrder(self.root) - #return self._getAncestorBST2(preorder, value1, value2) + #return self._getAncestorBST2(preorder, value1, value2) else: - return Exception('The tree is not a BST') - - + return Exception('The tree is not a BST') + + if __name__ == '__main__': import doctest doctest.testmod() diff --git a/src/graphs_and_trees/trees_basics/traversals.py b/src/trees/traversals/traversals.py similarity index 100% rename from src/graphs_and_trees/trees_basics/traversals.py rename to src/trees/traversals/traversals.py