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

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

@ -1,43 +1,23 @@
#!/usr/bin/python #!/usr/bin/python
__author__ = "Mari Wahl" __author__ = "bt3"
__email__ = "marina.w4hl@gmail.com"
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.item = item
self.level = level
self.left = None self.left = None
self.right = None self.right = None
def __repr__(self): def __repr__(self):
return '{}'.format(self.item) return '{}'.format(self.item)
def _addNextNode(self, value, level_here=1): def _add(self, value):
new_node = NodeBT(value, level_here) new_node = Node(value)
if not self.item: if not self.item:
self.item = new_node self.item = new_node
elif not self.left: elif not self.left:
@ -45,162 +25,93 @@ class NodeBT(object):
elif not self.right: elif not self.right:
self.right = new_node self.right = new_node
else: else:
self.left = self.left._addNextNode(value, level_here+1) self.left = self.left._add(value)
return self ## this is important, because the node return to the main return self
def _searchForNode(self, value): def _search(self, value):
if self.item == value: if self.item == value:
return self return True # or self
else:
found = None found = False # or False, thats diff from BST
if self.left: if self.left:
found = self.left._searchForNode(value) found = self.left._search(value)
if self.right:
found = found or self.right._searchForNode(value) if self.right:
return found found = found or self.right._search(value)
return found
def _isLeaf(self): def _isLeaf(self):
return not self.right and not self.left 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)
class BT(object):
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):
def __init__(self): def __init__(self):
self.root = None self.root = None
def addNode(self, value): def add(self, value):
if not self.root: if not self.root:
self.root = NodeBT(value) self.root = Node(value)
else: else:
self.root._addNextNode(value) self.root._add(value)
def isLeaf(self, value): def printPreorder(self):
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):
current = self.root current = self.root
nodes, stack = [], [] nodes, stack = [], []
while stack or current: while stack or current:
if current: if current:
nodes.append(current.item) # thats what change nodes.append(current.item) # this is what change
stack.append(current) stack.append(current)
current = current.left current = current.left
else: else:
current = stack.pop() current = stack.pop()
current = current.right 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__': if __name__ == '__main__':
bt = BinaryTree()
bt = BT()
print "Adding nodes 1 to 10 in the tree..." print "Adding nodes 1 to 10 in the tree..."
for i in range(1, 10): for i in range(1, 11):
bt.addNode(i) bt.add(i)
print "Is 8 a leaf? ", bt.isLeaf(8)
print "Whats the level of node 8? ", bt.getNodeLevel(8) print
print "Is node 10 a root? ", bt.isRoot(10) print "Searching for nodes 16 and 6"
print "Is node 1 a root? ", bt.isRoot(1) print bt.search(16)
print "Whats the tree height? ", bt.getHeight() print bt.search(6)
print "Is this tree BST? ", bt.isBST()
print "Is this tree balanced? ", bt.isBalanced() print
print (bt.preorder()) 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" __author__ = "bt3"
__email__ = "marina.w4hl@gmail.com"
class BunchClass(dict): class BunchClass(dict):
def __init__(self, *args, **kwds): 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_search_tree import BST, Node
from binary_tree import BT, Node from binary_tree import BT, Node

View File

@ -1,3 +1,5 @@
#!/usr/bin/env python
__author__ = "bt3" __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 """ """ A class for a simple tree """
class SimpleTree(object): class SimpleTree(object):
def __init__(self, value=None, children = None): def __init__(self, value=None, children = None):
self.value = value self.value = value
self.children = children 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