diff --git a/book/book_second_edition.pdf b/book/book_second_edition.pdf index 9838bdf..23a8b8b 100644 Binary files a/book/book_second_edition.pdf and b/book/book_second_edition.pdf differ diff --git a/src/trees/BST/BST.py b/src/trees/BST/BST.py deleted file mode 100644 index b2384a3..0000000 --- a/src/trees/BST/BST.py +++ /dev/null @@ -1,68 +0,0 @@ -#!/usr/bin/python3 -# mari von steinkirch @2013 -# steinkirch at gmail - -from BT import BT - -class BST(BT): - def __init__(self, value=None): - self.value = value - self.left = None - self.right = None - - def insert_left(self, new_node): - self.insert(value) - - def insert_right(self, new_node): - self.insert(value) - - - def insert(self, value): - if self.value == None: - self.value = value - else: - if value > self.value: - self.right = self.right and self.right.insert(value) or BST(value) - else: - self.left = self.left and self.left.insert(value) or BST(value) - return self - - def find(self, value): - if value == self.value: - return self - elif value > self.value and self.right: - return self.right.find(value) - elif self.left: - return self.left.find(value) - return None - - - - -def main(): - """ - BST - 4 - 2 6 - 1 3 5 7 - """ - tree = BST() - tree.insert(4) - tree.insert(2) - tree.insert(6) - tree.insert(1) - tree.insert(3) - tree.insert(7) - tree.insert(5) - print(tree.get_right()) - print(tree.get_right().get_left()) - print(tree.get_right().get_right()) - print(tree.get_left()) - print(tree.get_left().get_left()) - print(tree.get_left().get_right() == 1) - assert(tree.find(30) == None) - - -if __name__ == '__main__': - main() - diff --git a/src/trees/BST/BST_with_Nodes.py b/src/trees/BST/BST_with_Nodes.py deleted file mode 100644 index 91cd081..0000000 --- a/src/trees/BST/BST_with_Nodes.py +++ /dev/null @@ -1,66 +0,0 @@ -#!/usr/bin/python3 -# mari von steinkirch @2013 -# steinkirch at gmail - - - -class Node(object): - def __init__(self, value): - self.value = value - self.left = None - self.right = None - - def __repr__(self): - return '{}'.format(self.value) - - -class BSTwithNodes(object): - def __init__(self): - self.root = None - - - def insert(self, value): - if self.root == None: - self.root = Node(value) - else: - current = self.root - while True: - if value < current.value: - if current.left: - current = current.left - else: - current.left = Node(value) - break; - - elif value > current.value: - if current.right: - current = current.right - else: - current.right = Node(value) - break; - else: - break - - -def main(): - """ - BST - 4 - 2 6 - 1 3 5 7 - """ - tree = BSTwithNodes() - l1 = [4, 2, 6, 1, 3, 7, 5] - for i in l1: tree.insert(i) - print(tree.root) - print(tree.root.right) - print(tree.root.right.left) - print(tree.root.right.right) - print(tree.root.left) - print(tree.root.left.left) - print(tree.root.left.right) - - -if __name__ == '__main__': - main() - diff --git a/src/trees/BST/BT.py b/src/trees/BST/BT.py deleted file mode 100644 index 15d93b1..0000000 --- a/src/trees/BST/BT.py +++ /dev/null @@ -1,72 +0,0 @@ -#!/usr/bin/python3 -# mari von steinkirch @2013 -# steinkirch at gmail - - -class BT(object): - def __init__(self, value): - self.value = value - self.left = None - self.right = None - - - def get_right(self): - return self.right - - def get_left(self): - return self.left - - def is_leaf(self): - return self.left is None and self.right is None - - def set_root(self, obj): - self.value = obj - - def get_root(self): - return self.value - - def insert_left(self, new_node): - if self.left == None: - self.left = BT(new_node) - else: - t = BT(self.left) - t.left = new_node - self.left = t - - def insert_right(self, new_node): - if self.right == None: - self.right = BT(new_node) - else: - t = BT(self.right) - t.right = new_node - self.right = t - - def __repr__(self): - return '{}'.format(self.value) - - - -def tests_BT(): - """ - 1 - 2 3 - 4 5 6 7 - """ - tree = BT(1) - tree.insert_left(2) - tree.insert_right(3) - tree.get_left().insert_left(4) - tree.get_left().insert_right(5) - tree.get_right().insert_left(6) - tree.get_right().insert_right(7) - print(tree.get_right().get_right()) - tree.get_right().get_right().set_root(8) - print(tree.get_right().get_right()) - assert(tree.get_right().is_leaf() == False) - assert(tree.get_right().get_right().is_leaf() == True) - print("Tests Passed!") - - -if __name__ == '__main__': - tests_BT() - diff --git a/src/trees/BST/BT_lists.py b/src/trees/BST/BT_lists.py deleted file mode 100644 index 7e6c1c5..0000000 --- a/src/trees/BST/BT_lists.py +++ /dev/null @@ -1,61 +0,0 @@ -#!/usr/bin/python3 -# mari von steinkirch @2013 -# steinkirch at gmail - - -def BinaryTreeList(r): - ''' 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 ''' - 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/trees/BST/__init__.py b/src/trees/BST/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/src/trees/BST/avl.py b/src/trees/BST/avl.py deleted file mode 100644 index ca23adc..0000000 --- a/src/trees/BST/avl.py +++ /dev/null @@ -1,140 +0,0 @@ -#!/usr/bin/python3 -# mari von steinkirch @2013 -# steinkirch at gmail - -from BST_with_Nodes import BSTwithNodes, Node - - -class AVL(BSTwithNodes): - """AVL binary search tree implementation. - Supports insert, find, and delete-min operations in O(lg n) time. - """ - def __init__(self): - self.root = None - - def left_rotate(self, x): - y = x.right - y.value = x.value - if y.value is None: - self.root = y - else: - if y.value.left is x: - y.value.left = y - elif y.value.right is x: - y.value.right = y - x.right = y.left - if x.right is not None: - x.right.value = x - y.left = x - x.value = y - update_height(x) - update_height(y) - - def right_rotate(self, x): - y = x.left - y.value = x.value - if y.value is None: - self.root = y - else: - if y.value.left is x: - y.value.left = y - elif y.value.right is x: - y.value.right = y - x.left = y.right - if x.left is not None: - x.left.value = x - y.right = x - x.value = y - update_height(x) - update_height(y) - - def insert_item(self, value): - if self.root == None: - self.root = Node(value) - else: - current = self.root - while True: - if value < current.value: - if current.left: - current = current.left - else: - current.left = Node(value) - break; - - elif value > current.value: - if current.right: - current = current.right - else: - current.right = Node(value) - break; - else: - break - - - def insert(self, value): - node = self.insert_item(value) - self.rebalance(node) - - - def rebalance(self, node): - while node is not None: - update_height(node) - if height(node.left) >= 2 + height(node.right): - if height(node.left.left) >= height(node.left.right): - self.right_rotate(node) - else: - self.left_rotate(node.left) - self.right_rotate(node) - elif height(node.right) >= 2 + height(node.left): - if height(node.right.right) >= height(node.right.left): - self.left_rotate(node) - else: - self.right_rotate(node.right) - self.left_rotate(node) - node = node.value - - - def inorder(self, node): - if node is not None: - self.inorder(node.left) - print(node.value) - self.inorder(node.right) - - def preorder(self, node): - if node is not None: - print(node.value) - self.preorder(node.left) - self.preorder(node.right) - - def postorder(self, node): - if node is not None: - self.postorder(node.left) - self.postorder(node.right) - print(node.value) - - -def height(node): - if node is None: return -1 - else: return node.height - -def update_height(node): - node.height = max(height(node.left), height(node.right)) + 1 - - - -def main(): - tree = AVL() - tree.insert(4) - tree.insert(2) - tree.insert(6) - tree.insert(1) - tree.insert(3) - tree.insert(7) - tree.insert(5) - print('Inorder Traversal:') - tree.inorder(tree.root) - - - -if __name__ == '__main__': - main() diff --git a/src/trees/BST/binary_search_tree.py b/src/trees/BST/binary_search_tree.py deleted file mode 100644 index a58c937..0000000 --- a/src/trees/BST/binary_search_tree.py +++ /dev/null @@ -1,102 +0,0 @@ -#!/usr/bin/python3 -# mari von steinkirch 2013 - -from binary_tree import BinaryTree, NodeBT - -''' Implementation of a binary search tree and its properties. - We use the Binary Tree class and its Node class as superclasses, and we modify the methods - that are needeed to create a BST (polymorphism). For example, the following bst: - - 7 ---> level 0 - 4 9 ---> level 1 - 2 5 8 10 ---> level 2 - 1 6 ---> level 3 - - has the following properties: - - - SIZE OR NUMBER OF NODES: n = 10 - - NUMBER OF BRANCHES OR INTERNAL NODES: b = n-1 = 9 - - VALUE OF ROOT = 7 - - MAX_DEPTH OR HEIGHT: h = 3 - - IS BALANCED? YES - - IS BST? YES - - INORDER DFT: 1, 2, 4, 5, 6, 7, 8, 9, 10 - - POSTORDER DFT: 1, 2, 6, 5, 4, 8, 10, 9, 7 - - PREORDER DFT: 7, 4, 2, 1, 5, 6, 9, 8, 10 - - BFT: 7, 4, 9, 2, 5, 8, 10, 1, 6 -''' - - -class NodeBST(NodeBT): - - def _addNextNode(self, value, level_here=1): - ''' Aux for self.addNode(value): for BST, best O(1), worst O(log n) ''' - self.traversal = [] - new_node = NodeBST(value, level_here) - if not self.item: - self.item = new_node - elif value < self.item: - self.left = self.left and self.left._addNextNode(value, level_here+1) or new_node - else: - self.right = self.right and self.right._addNextNode(value, level_here+1) or new_node - return self - - def _searchForNode(self, value): - ''' Traverse the tree looking for the node. For BST it is O(logn) if the - tree is balanced, otherwise it can be O(n) ''' - if self.item == value: return self - elif value > self.item and self.right: return self.right._findNode(value) - elif value < self.item and self.left: return self.left._findNode(value) - return None - - - -class BinarySearchTree(BinaryTree): - ''' - >>> bst = BinarySearchTree() - >>> l1 = [7, 4, 5, 9, 2, 8, 1, 6, 10] - >>> for i in l1: bst.addNode(i) - >>> bst.hasNode(3) - False - >>> bst.hasNode(10) - True - >>> bst.printTree('pre') - [7, 4, 2, 1, 5, 6, 9, 8, 10] - >>> bst.printTree('post') - [1, 2, 6, 5, 4, 8, 10, 9, 7] - >>> bst.printTree('in') - [1, 2, 4, 5, 6, 7, 8, 9, 10] - >>> bst.printTree('bft') - [7, 4, 9, 2, 5, 8, 10, 1, 6] - >>> bst.getHeight() - 3 - >>> bst.isBST() - True - >>> bst.isBalanced() - False - >>> bst.isBalanced(2) - False - >>> bst.getAncestor(2, 9) - 7 - >>> bst.getAncestor(2, 9, 'bst') - 7 - >>> bst.getAncestor(2, 9, 'pre-post') - 7 - >>> bst.getAncestor(2, 9, 'post-in') - 7 - ''' - - - def addNode(self, value): - ''' Add new node to the tree, by the left first, O(n). - The only difference from the Binary Tree class is the node class is - NodeBST and not NodeBT ''' - if not self.root: self.root = NodeBST(value) - else: self.root._addNextNode(value) - - - -if __name__ == '__main__': - import doctest - doctest.testmod() - diff --git a/src/trees/BST/veritfy_if_BST.py b/src/trees/BST/veritfy_if_BST.py deleted file mode 100644 index 8aeb9c1..0000000 --- a/src/trees/BST/veritfy_if_BST.py +++ /dev/null @@ -1,56 +0,0 @@ -#!/usr/bin/python3 -# mari von steinkirch @2013 -# steinkirch at gmail - - -from BT import BT - -def is_bst(root, min=float('-inf'), max=float('inf')): - left, right, value = root.left, root.right, root.value - if min < value < max: - if left and right: - return is_bst(left, min, value) and is_bst(right, value, max) - elif left: - return is_bst(left, min, value) - elif right: - return is_bst(right, value, max) - return True - return False - - -def main(): - """ - BST - 4 - 2 6 - 1 3 5 7 - - BT - 4 - 2 6 - 1 8 5 7 - """ - bst = BT(4) - bst.insert_left(2) - bst.insert_right(6) - bst.get_left().insert_left(1) - bst.get_left().insert_right(3) - bst.get_right().insert_left(5) - bst.get_right().insert_right(7) - print('is_bst(bst) =', is_bst(bst)) - - bt = BT(4) - bt.insert_left(2) - bt.insert_right(6) - bt.get_left().insert_left(1) - bt.get_left().insert_right(8) - bt.get_right().insert_left(5) - bt.get_right().insert_right(7) - print('is_bst(bt) =', is_bst(bt)) - - -if __name__ == '__main__': - main() - - - diff --git a/src/trees/binary_search_tree.py b/src/trees/binary_search_tree.py new file mode 100644 index 0000000..da35caf --- /dev/null +++ b/src/trees/binary_search_tree.py @@ -0,0 +1,73 @@ +#!/usr/bin/python + +__author__ = "Mari Wahl" +__email__ = "marina.w4hl@gmail.com" + + +from binary_tree import NodeBT, BinaryTree + + +class NodeBST(NodeBT): + + def __init__(self, item=None, level=0): + self.item = item + self.level = level + self.left = None + self.right = None + + + 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 + elif value < self.item: + self.left = self.left and self.left._addNextNode(value, level_here+1) or new_node + else: + print("BSTs do not support repeated items.") + return self # this is necessary!!! + + + + def _searchForNode(self, value): + if self.item == value: + return self + elif self.left and value < self.item: + return self.left._searchForNode(value) + elif self.right and value > self.item: + return self.right._searchForNode(value) + else: + return False + + + +class BinarySearchTree(BinaryTree): + + def __init__(self): + self.root = None + + def addNode(self, value): + if not self.root: + self.root = NodeBST(value) + else: + self.root._addNextNode(value) + + + + +if __name__ == '__main__': + bst = BinarySearchTree() + 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() + + diff --git a/src/trees/binary_trees_and_others/binary_tree.py b/src/trees/binary_tree.py similarity index 100% rename from src/trees/binary_trees_and_others/binary_tree.py rename to src/trees/binary_tree.py diff --git a/src/trees/binary_trees_and_others/__init__.py b/src/trees/binary_trees_and_others/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/src/trees/binary_trees_and_others/binary_tree_lists.py b/src/trees/binary_trees_and_others/binary_tree_lists.py deleted file mode 100644 index 966cb33..0000000 --- a/src/trees/binary_trees_and_others/binary_tree_lists.py +++ /dev/null @@ -1,64 +0,0 @@ -#!/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/trees/binary_trees_and_others/bunchclass.py b/src/trees/bunchclass.py similarity index 100% rename from src/trees/binary_trees_and_others/bunchclass.py rename to src/trees/bunchclass.py diff --git a/src/trees/binary_trees_and_others/tree.py b/src/trees/tree.py similarity index 100% rename from src/trees/binary_trees_and_others/tree.py rename to src/trees/tree.py