trees organized

This commit is contained in:
Mari Wahl 2015-01-07 13:43:37 -05:00
parent 28b84cef65
commit 52752fb931
16 changed files with 262 additions and 689 deletions

0
src/trees/__init__.py Normal file → Executable file
View File

90
src/trees/binary_search_tree.py Normal file → Executable file
View File

@ -1,73 +1,103 @@
#!/usr/bin/python
__author__ = "Mari Wahl"
__email__ = "marina.w4hl@gmail.com"
__author__ = "bt3"
from binary_tree import NodeBT, BinaryTree
class Node(object):
def __init__(self, item=None,):
class NodeBST(NodeBT):
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 _add(self, value):
new_node = Node(value)
def _addNextNode(self, value, level_here=1):
new_node = NodeBST(value, level_here)
if not self.item:
self.item = new_node
else:
if value > self.item:
self.right = self.right and self.right._addNextNode(value, level_here+1) or new_node
self.right = self.right and self.right._add(value) or new_node
elif value < self.item:
self.left = self.left and self.left._addNextNode(value, level_here+1) or new_node
self.left = self.left and self.left._add(value) or new_node
else:
print("BSTs do not support repeated items.")
return self # this is necessary!!!
def _searchForNode(self, value):
def _search(self, value):
if self.item == value:
return self
return True # or self
elif self.left and value < self.item:
return self.left._searchForNode(value)
return self.left._search(value)
elif self.right and value > self.item:
return self.right._searchForNode(value)
return self.right._search(value)
else:
return False
def _isLeaf(self):
return not self.right and not self.left
class BinarySearchTree(BinaryTree):
def _printPreorder(self):
print self.item
if self.left:
return self.left._printPreorder()
if self.right:
return self.right._printPreorder()
class BST(object):
def __init__(self):
self.root = None
def addNode(self, value):
def add(self, value):
if not self.root:
self.root = NodeBST(value)
self.root = Node(value)
else:
self.root._addNextNode(value)
self.root._add(value)
def printPreorder(self):
if self.root:
self.root._printPreorder()
def search(self, value):
if self.root:
return self.root._search(value)
if __name__ == '__main__':
bst = BinarySearchTree()
bst = BST()
print "Adding nodes 1 to 10 in the tree..."
for i in range(1, 10):
bst.addNode(i)
print "Is 8 a leaf? ", bst.isLeaf(8)
print "Whats the level of node 8? ", bst.getNodeLevel(8)
print "Is node 10 a root? ", bst.isRoot(10)
print "Is node 1 a root? ", bst.isRoot(1)
print "Whats the tree height? ", bst.getHeight()
print "Is this tree BST? ", bst.isBST()
print "Is this tree balanced? ", bst.isBalanced()
for i in range(1, 11):
bst.add(i)
print
print "Searching for nodes 16 and 6"
print bst.search(16)
print bst.search(6)
print
print "Printing preorder..."
bst.printPreorder()

213
src/trees/binary_tree.py Normal file → Executable file
View File

@ -1,43 +1,23 @@
#!/usr/bin/python
__author__ = "Mari Wahl"
__email__ = "marina.w4hl@gmail.com"
__author__ = "bt3"
class Node(object):
''' Implementation of a binary tree and its properties. For example, the following bt:
def __init__(self, item=None,):
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)
def _add(self, value):
new_node = Node(value)
if not self.item:
self.item = new_node
elif not self.left:
@ -45,19 +25,21 @@ class NodeBT(object):
elif not self.right:
self.right = new_node
else:
self.left = self.left._addNextNode(value, level_here+1)
return self ## this is important, because the node return to the main
def _searchForNode(self, value):
if self.item == value:
self.left = self.left._add(value)
return self
else:
found = None
def _search(self, value):
if self.item == value:
return True # or self
found = False # or False, thats diff from BST
if self.left:
found = self.left._searchForNode(value)
found = self.left._search(value)
if self.right:
found = found or self.right._searchForNode(value)
found = found or self.right._search(value)
return found
@ -65,142 +47,71 @@ class NodeBT(object):
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, mintree=None, maxtree=None):
''' Find whether the tree is a BST, inorder '''
if self.item:
if not mintree:
mintree = self.item
if not maxtree:
maxtree = self.item
if self._isLeaf():
return True
elif self.left:
if self.left.item < self.item and mintree > self.left.item:
mintree = self.left.item
return self.left._isBST(mintree, maxtree)
else:
return False
elif self.right:
if self.right.item > self.item and maxtree < self.right.item:
maxtree = self.right.item
return self.right._isBST(mintree, maxtree)
else:
return False
else:
print('Tree is empty')
class BinaryTree(object):
class BT(object):
def __init__(self):
self.root = None
def addNode(self, value):
def add(self, value):
if not self.root:
self.root = NodeBT(value)
self.root = Node(value)
else:
self.root._addNextNode(value)
self.root._add(value)
def isLeaf(self, value):
node = self.root._searchForNode(value)
if node:
return node._isLeaf()
else:
print "Node not found."
def getNodeLevel(self, item):
node = self.root._searchForNode(item)
if node:
return node.level
else:
print('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()
def preorder(self):
def printPreorder(self):
current = self.root
nodes, stack = [], []
while stack or current:
if current:
nodes.append(current.item) # thats what change
nodes.append(current.item) # this is what change
stack.append(current)
current = current.left
else:
current = stack.pop()
current = current.right
return nodes
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)
if __name__ == '__main__':
bt = BinaryTree()
bt = BT()
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()
print (bt.preorder())
for i in range(1, 11):
bt.add(i)
print
print "Searching for nodes 16 and 6"
print bt.search(16)
print bt.search(6)
print
print "Printing preorder..."
bt.printPreorder()
print "Printing Inorder..."
bt.printInorder()

5
src/trees/bunchclass.py Normal file → Executable file
View File

@ -1,7 +1,6 @@
#!/usr/bin/python
#!/usr/bin/env python
__author__ = "Mari Wahl"
__email__ = "marina.w4hl@gmail.com"
__author__ = "bt3"
class BunchClass(dict):
def __init__(self, *args, **kwds):

40
src/trees/check_ancestor.py Executable file
View File

@ -0,0 +1,40 @@
#!/usr/bin/env python
__author__ = "bt3"
from binary_search_tree import BST, Node
from transversal import inorder
def find_ancestor(path, low_value, high_value):
while path:
current_value = path[0]
if current_value < low_value:
try:
path = path[2:]
except:
return current_value
elif current_value > high_value:
try:
path = path[1:]
except:
return current_value
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)
print 'Original: ', l
print 'Inorder: ', nodes
print 'Ancestor for 3, 11:', find_ancestor(nodes, 3, 11)

View File

@ -1,5 +1,6 @@
__author__ = "bt3"
#!/usr/bin/env python
__author__ = "bt3"
from binary_search_tree import BST, Node
from binary_tree import BT, Node

View File

@ -1,3 +1,5 @@
#!/usr/bin/env python
__author__ = "bt3"

7
src/trees/tree.py → src/trees/simple_tree.py Normal file → Executable file
View File

@ -1,11 +1,12 @@
#!/usr/bin/python
#!/usr/bin/env python
__author__ = "bt3"
__author__ = "Mari Wahl"
__email__ = "marina.w4hl@gmail.com"
""" A class for a simple tree """
class SimpleTree(object):
def __init__(self, value=None, children = None):
self.value = value
self.children = children

89
src/trees/transversal.py Executable file
View File

@ -0,0 +1,89 @@
#!/usr/bin/env python
__author__ = "bt3"
from collections import deque
from binary_search_tree import BST, Node
from binary_tree import BT, Node
def BFT(tree):
current = tree.root
nodes = []
queue = deque()
queue.append(current)
while queue:
current = queue.popleft()
nodes.append(current.item)
if current.left:
queue.append(current.left)
if current.right:
queue.append(current.right)
return nodes
def preorder(tree, nodes=None):
nodes = nodes or []
if tree:
nodes.append(tree.item)
if tree.left:
preorder(tree.left, nodes)
if tree.right:
preorder(tree.right, nodes)
return nodes
def postorder(tree, nodes=None):
nodes = nodes or []
if tree:
if tree.left:
nodes = postorder(tree.left, nodes)
if tree.right:
nodes = postorder(tree.right, nodes)
nodes.append(tree.item)
return nodes
def inorder(tree, nodes=None):
nodes = nodes or []
if tree:
if tree.left:
nodes = inorder(tree.left, nodes)
nodes.append(tree.item)
if tree.right:
nodes = inorder(tree.right, nodes)
return nodes
if __name__ == '__main__':
# bt
bt = BT()
l = [10, 5, 6, 3, 8, 2, 1, 11, 9, 4]
for i in l:
bt.add(i)
print 'BT...'
print 'Original: ', l
print 'Preorder: ', preorder(bt.root)
print 'Postorder: ', postorder(bt.root)
print 'Inorder: ', inorder(bt.root)
print 'Breath: ', BFT(bt)
# bst
bst = BST()
l = [10, 5, 6, 3, 8, 2, 1, 11, 9, 4]
for i in l:
bst.add(i)
print
print 'BST ...'
print 'Original: ', l
print 'Preorder: ', preorder(bst.root)
print 'Postorder: ', postorder(bst.root)
print 'Inorder: ', inorder(bst.root)
print 'Breath: ', BFT(bst)

View File

@ -1,44 +0,0 @@
#!/usr/bin/python
__author__ = "Mari Wahl"
__email__ = "marina.w4hl@gmail.com"
''' find the lowest ancestor in a BST '''
from transversal_BST_recursively import BSTwithTransversalRecursively
def find_ancestor(path, low_value, high_value):
while path:
current_value = path[0]
if current_value < low_value:
try:
path = path[2:]
except:
return current_value
elif current_value > high_value:
try:
path = path[1:]
except:
return current_value
elif low_value <= current_value <= high_value:
return current_value
else:
return None # this is probably never touched
if __name__ == '__main__':
bst = BSTwithTransversalRecursively()
l = [10, 5, 15, 1, 6, 11, 50]
for i in l:
bst.addNode(i)
path = bst.preorder()
print("The path inorder: ", path)
print("The path between 1 and 6 is :", find_ancestor(path, 1, 6))
print("The path between 1 and 11 is: ", find_ancestor(path, 1, 11))
print("The path between 11 and 50 is: ", find_ancestor(path, 11, 50))
print("The path between 5 and 15 is: ", find_ancestor(path, 5, 15))

View File

@ -1,91 +0,0 @@
#!/usr/bin/python
__author__ = "Mari Wahl"
__email__ = "marina.w4hl@gmail.com"
from collections import deque
from binary_search_tree import BinarySearchTree, NodeBST
class BSTwithTransversalIterative(BinarySearchTree):
def inorder(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) # thats what change
current = current.right
return nodes
def preorder(self):
current = self.root
nodes, stack = [], []
while stack or current:
if current:
nodes.append(current.item) # thats what change
stack.append(current)
current = current.left
else:
current = stack.pop()
current = current.right
return nodes
def preorder2(self):
nodes = []
stack = [self.root]
while stack:
current = stack.pop()
if current:
nodes.append(current.item)
stack.append(current.right)
stack.append(current.left)
return nodes
def BFT(self):
current = self.root
nodes = []
queue = deque()
queue.append(current)
while queue:
current = queue.popleft()
nodes.append(current.item)
if current.left:
queue.append(current.left) # LEFT FIRST!
if current.right:
queue.append(current.right)
return nodes
if __name__ == '__main__':
bst = BSTwithTransversalIterative()
l = [10, 5, 6, 3, 8, 2, 1, 11, 9, 4]
for i in l:
bst.addNode(i)
print "Is 8 a leaf? ", bst.isLeaf(8)
print "Whats the level of node 8? ", bst.getNodeLevel(8)
print "Is node 10 a root? ", bst.isRoot(10)
print "Is node 1 a root? ", bst.isRoot(1)
print "Whats the tree height? ", bst.getHeight()
print "Is this tree BST? ", bst.isBST()
print "Is this tree balanced? ", bst.isBalanced()
print("Pre-order I: ", bst.preorder())
print("Pre-order II: ", bst.preorder2())
print("In-order: ", bst.inorder())
print("BFT: ", bst.BFT())

View File

@ -1,88 +0,0 @@
#!/usr/bin/python
__author__ = "Mari Wahl"
__email__ = "marina.w4hl@gmail.com"
from binary_search_tree import BinarySearchTree, NodeBST
class BSTwithTransversalRecursively(BinarySearchTree):
def __init__(self):
self.root = None
self.nodes_BFS = []
self.nodes_pre = []
self.nodes_post = []
self.nodes_in = []
def BFT(self):
self.root.level = 0
queue = [self.root]
current_level = self.root.level
while len(queue) > 0:
current_node = queue.pop(0)
if current_node.level > current_level:
current_level += 1
self.nodes_BFS.append(current_node.item)
if current_node.left:
current_node.left.level = current_level + 1
queue.append(current_node.left)
if current_node.right:
current_node.right.level = current_level + 1
queue.append(current_node.right)
return self.nodes_BFS
def inorder(self, node=None, level=0):
if not node and level == 0:
node = self.root
if node:
self.inorder(node.left, level+1)
self.nodes_in.append(node.item)
self.inorder(node.right, level+1)
return self.nodes_in
def preorder(self, node=None, level=0):
if not node and level == 0:
node = self.root
if node:
self.nodes_pre.append(node.item)
self.preorder(node.left, level+1)
self.preorder(node.right, level+1)
return self.nodes_pre
def postorder(self, node=None, level=0):
if not node and level == 0:
node = self.root
if node:
self.postorder(node.left, level+1)
self.postorder(node.right, level+1)
self.nodes_post.append(node.item)
return self.nodes_post
if __name__ == '__main__':
bst = BSTwithTransversalRecursively()
l = [10, 5, 6, 3, 8, 2, 1, 11, 9, 4]
for i in l:
bst.addNode(i)
print "Is 8 a leaf? ", bst.isLeaf(8)
print "Whats the level of node 8? ", bst.getNodeLevel(8)
print "Is node 10 a root? ", bst.isRoot(10)
print "Is node 1 a root? ", bst.isRoot(1)
print "Whats the tree height? ", bst.getHeight()
print "Is this tree BST? ", bst.isBST()
print "Is this tree balanced? ", bst.isBalanced()
print("Pre-order: ", bst.preorder())
print("Post-order: ", bst.postorder())
print("In-order: ", bst.inorder())
print("BFT: ", bst.BFT())

View File

@ -1,103 +0,0 @@
#!/usr/bin/python
__author__ = "bt3"
class Node(object):
def __init__(self, item=None,):
self.item = item
self.left = None
self.right = None
def __repr__(self):
return '{}'.format(self.item)
def _add(self, value):
new_node = Node(value)
if not self.item:
self.item = new_node
else:
if value > self.item:
self.right = self.right and self.right._add(value) or new_node
elif value < self.item:
self.left = self.left and self.left._add(value) or new_node
else:
print("BSTs do not support repeated items.")
return self # this is necessary!!!
def _search(self, value):
if self.item == value:
return True # or self
elif self.left and value < self.item:
return self.left._search(value)
elif self.right and value > self.item:
return self.right._search(value)
else:
return False
def _isLeaf(self):
return not self.right and not self.left
def _printPreorder(self):
print self.item
if self.left:
return self.left._printPreorder()
if self.right:
return self.right._printPreorder()
class BST(object):
def __init__(self):
self.root = None
def add(self, value):
if not self.root:
self.root = Node(value)
else:
self.root._add(value)
def printPreorder(self):
if self.root:
self.root._printPreorder()
def search(self, value):
if self.root:
return self.root._search(value)
if __name__ == '__main__':
bst = BST()
print "Adding nodes 1 to 10 in the tree..."
for i in range(1, 11):
bst.add(i)
print
print "Searching for nodes 16 and 6"
print bst.search(16)
print bst.search(6)
print
print "Printing preorder..."
bst.printPreorder()

View File

@ -1,122 +0,0 @@
#!/usr/bin/python
__author__ = "bt3"
class Node(object):
def __init__(self, item=None,):
self.item = item
self.left = None
self.right = None
def __repr__(self):
return '{}'.format(self.item)
def _add(self, value):
new_node = Node(value)
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._add(value)
return self
def _search(self, value):
if self.item == value:
return True # or self
found = False # or False, thats diff from BST
if self.left:
found = self.left._search(value)
if self.right:
found = found or self.right._search(value)
return found
def _isLeaf(self):
return not self.right and not self.left
class BT(object):
def __init__(self):
self.root = None
def add(self, value):
if not self.root:
self.root = Node(value)
else:
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 printPostorder(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)
if __name__ == '__main__':
bt = BT()
print "Adding nodes 1 to 10 in the tree..."
for i in range(1, 11):
bt.add(i)
print
print "Searching for nodes 16 and 6"
print bt.search(16)
print bt.search(6)
print
print "Printing preorder..."
bt.printPreorder()
print
print "Printing postorder..."
bt.printPostorder()
print
print "Printing Inorder..."
bt.printInorder()

View File

@ -1,52 +0,0 @@
#!/usr/bin/env python
__author__ = "bt3"
'''
Reconstruct a binary tree given two sequences of node traversals,
one from inorder and one from postorder traversal.
'''
class Node(object):
def __init__(self, value, right=None, left=None):
self.value = value
self.right = right
self.left = left
def create_tree():
tree = Node(4)
tree.right = Node(6)
tree.left = Node(2)
tree.right.left = Node(5)
tree.right.right = Node(7)
tree.left.left = Node(1)
tree.left.right = Node(3)
return tree
def inorder(tree):
if tree:
if tree.left:
inorder(tree.left)
print tree.value
if tree.right:
inorder(tree.right)
def postorder(tree):
if tree:
if tree.left:
postorder(tree.left)
if tree.right:
postorder(tree.right)
print tree.value
if __name__ == '__main__':
tree = create_tree()
print 'Printing inorder...'
inorder(tree)
print
print 'Printing postorder...'
postorder(tree)

0
src/trees/trees/trie.py → src/trees/trie.py Normal file → Executable file
View File