def test_tree_maker():
	'''
        1
      /   \	
     2     3
   /        \
  4          5	
	'''
	btree = BinaryTree.fromList([1, 2, 3, 4, None, None, 5])
	assert btree is not None
	assert btree.root is not None

	assert btree.root.value == 1
	assert btree.root.left.value == 2
	assert btree.root.right.value == 3

	assert btree.root.left.left.value == 4
	assert btree.root.left.right == None
	assert btree.root.right.left == None
	assert btree.root.right.right.value == 5

	assert btree.root.left.left.left == None
	assert btree.root.left.left.right == None
	assert btree.root.right.right.left == None
	assert btree.root.right.right.right == None

	'''
							1
						  /   \	
						 2     3
					   /  \  /  \
					  4   5 6    7

	In-order traversal:  [4,2,5,1,6,3,7]
	Pre-order traversal: [1,2,4,5,3,6,7]
	Post-order traversal: [4,5,2,6,7,3,1]
	'''
	btree = BinaryTree.from_traversal([4,2,5,1,6,3,7], [1,2,4,5,3,6,7])
	assert btree is not None
	assert btree.root is not None

	# Compare inorder and preorder traversals of the resulting tree
	inorder, preorder = [], []
	aggregate_list = lambda kwargs, data : kwargs['lst'].append(data)
	btree.preorder_traversal(aggregate_list, lst=preorder)
	btree.inorder_traversal(aggregate_list, lst=inorder)
	assert inorder == [4,2,5,1,6,3,7]
	assert preorder ==  [1,2,4,5,3,6,7]
	
	btree = BinaryTree.from_traversal([4,2,5,1,6,3,7], postorder=[4,5,2,6,7,3,1])
	assert btree is not None
	assert btree.root is not None

	# Compare inorder and postorder traversals of the resulting tree
	inorder, postorder = [], []
	aggregate_list = lambda kwargs, data : kwargs['lst'].append(data)
	btree.postorder_traversal(aggregate_list, lst=postorder)
	btree.inorder_traversal(aggregate_list, lst=inorder)
	assert inorder ==[4,2,5,1,6,3,7]
	assert postorder == [4,5,2,6,7,3,1]
Beispiel #2
0
    def from_traversal_in_post(inorder, postorder):
        # some checks to see if the inputs are in order (heh!)
        if not inorder or not postorder:
            return None

        if len(inorder) != len(postorder):
            return None

        # helper function to recursively build the binary tree
        # NOTE: Assumes no duplicates FIXME
        def _from_traversal(inorder, postorder):
            # Empty traversal lists, return empty node
            if not inorder:
                return None

            # Create root node for this subtree
            root = Node(postorder[-1])

            # Locate root in inorder traversal sequence
            root_idx = inorder.index(postorder[-1])

            root.left = _from_traversal(inorder[:root_idx],
                                        postorder[:root_idx])
            root.right = _from_traversal(inorder[root_idx + 1:],
                                         postorder[root_idx:-1])

            return root

        # call the helper function
        root = _from_traversal(inorder, postorder)
        return BinaryTree(root)
def populated_tree_2():
    n1 = Node(42)
    n2 = Node(100)
    n3 = Node(600)
    n4 = Node(15)
    n5 = Node(160)
    n6 = Node(200)
    n7 = Node(350)
    n8 = Node(125)
    n9 = Node(175)
    n10 = Node(4)
    n11 = Node(500)
    n1.left = n2
    n1.right = n3
    n2.left = n4
    n2.right = n5
    n3.left = n6
    n3.right = n7
    n5.left = n8
    n5.right = n9
    n7.left = n10
    n7.right = n11

    bt = BinaryTree(n1)

    return bt
def test_zigzag_traversal():
    '''
        1
      /   \	
     2     3
   /        \
  4          5	
	'''
    btree = BinaryTree.fromList([1, 2, 3, 4, None, None, 5])
    assert btree is not None
    assert btree.root is not None

    collate_fn = lambda kwargs, data: kwargs['lst'].append(data)

    l = []
    btree.zigzag_levelorder_traversal(collate_fn, lst=l)
    assert (l == [1, 3, 2, 4, 5])
    '''
							1
						  /   \	
						 2     3
					   /  \  /  \
					  4   5 6    7

	'''
    btree = BinaryTree.fromList([1, 2, 3, 4, 5, 6, 7])
    assert btree is not None
    assert btree.root is not None
    l = []
    btree.zigzag_levelorder_traversal(collate_fn, lst=l)
    assert (l == [1, 3, 2, 4, 5, 6, 7])
    '''
							a
						  /   \	
						 b     c
					   /  \  /  \
					  d   e f    g
					 /            \
					h              i
	'''
    btree = BinaryTree.fromList("abcdefghi")
    assert btree is not None
    assert btree.root is not None
    l = []
    btree.zigzag_levelorder_traversal(collate_fn, lst=l)
    assert (''.join(l) == "acbdefgih")
Beispiel #5
0
    def clone_r(bintree):
        def _clone(root):
            if not root:
                return None

            root_ = Node(root.value)
            root_.left = _clone(root.left)
            root_.right = _clone(root.right)
            return root_

        if not bintree or not bintree.root:
            return None

        return BinaryTree(root=_clone(bintree.root))
Beispiel #6
0
    def clone_i(bintree):
        s = Stack()
        # contains cloned node references, a', for each node a
        # doubles as visited[] map => if cloned_nodes[a] is not empty => a is visited
        cloned_nodes = {}

        if not bintree or not bintree.root:
            return None

        # Helper function to check if a node is already 'done'/processed
        # a node is considered 'done'
        #   if its value is None
        #   or
        #   if it has already been cloned.
        isDone = lambda node, cloned_node: True if (node is None or cloned_node
                                                    is not None) else False

        s.push(bintree.root)
        while s:
            node = s.top()
            left_clone = cloned_nodes.get(node.left)
            right_clone = cloned_nodes.get(node.right)
            # Both left and right subtrees are done
            # pop 'node' off the stack, create a clone, and map the clone to the original
            # Link cloned node's left and right children
            if isDone(node.left, left_clone) and isDone(
                    node.right, right_clone):
                s.pop()
                node_ = Node(node.value)
                node_.left = left_clone
                node_.right = right_clone
                cloned_nodes[node] = node_
            else:
                # push both left and right children to the stack
                # NOTE: This actually processes reverse post-order (right-left-root)
                #       unless we push right, followed by left onto the stack
                #       but order shouldnt really matter
                s.push(node.left) if node.left else None
                s.push(node.right) if node.right else None

        return BinaryTree(root=cloned_nodes[bintree.root])
Beispiel #7
0
    def fromList(array):
        # lambda helper functions to get parent, left, and right nodes indices
        # from current index
        parent = lambda i: (i - 1) / 2
        left = lambda i: 2 * i + 1
        right = lambda i: 2 * i + 2

        # All odd indices are left children,
        # even indices are right children in the binary tree
        isLeftChild = lambda i: (i & 1 == 1)

        # root cannot be empty
        if not array or array[0] is None:
            return None

        root = Node(array[0])
        btree = BinaryTree(root)
        nodes_list = [root]

        for i in xrange(1, len(array)):
            n = None
            if array[i] is not None:
                n = Node(array[i])

            p = nodes_list[parent(i)]
            if p is None:
                continue

            if isLeftChild(i):
                p.left = n
            else:
                p.right = n

            nodes_list.append(n)

        return btree
def empty_tree_1():
    return BinaryTree()
def traversals():
	# prefix equation tree : "+a*bc"
	'''
	     +
	   /   \	
      a     *
	      /   \
	     b     c
	'''		 

	root = Node("+")
	lnode = Node("a")
	rnode = Node("*")
	root.setChildren(lnode, rnode)

	rlnode = Node("b")
	rrnode = Node("c")
	rnode.setChildren(rlnode, rrnode)

	btree = BinaryTree(root)


	print 'Preorder: ',
	btree.preorder_traversal()
	print

	l = []
	# define a lambda function that collates individual node values into a list
	collate_fn = lambda kwargs, data : kwargs['lst'].append(data)
	btree.preorder_traversal(collate_fn, lst=l)
	assert (l == ['+', 'a', '*', 'b', 'c'])

	print 'Postorder: ',
	btree.postorder_traversal()
	print

	l = []
	btree.postorder_traversal(collate_fn, lst=l)
	assert (l == ['a',  'b', 'c', '*', '+'])

	print 'Inorder: ',
	btree.inorder_traversal()
	print

	l = []
	btree.inorder_traversal(collate_fn, lst=l)
	assert (l == ['a', '+', 'b', '*', 'c'])

	print 'Level order: ',
	btree.levelorder_traversal()
	print

	l = []
	btree.levelorder_traversal(collate_fn, lst=l)
	assert (l == ['+', 'a', '*', 'b', 'c'])


	print 'Left View: ',
	btree.left_view()
	print

	l = []
	btree.left_view(collate_fn, lst=l)
	assert (l == ['+', 'a',  'b'])

	print 'Right View: ',
	btree.right_view()
	print

	l = []
	btree.right_view(collate_fn, lst=l)
	assert (l == ['+', '*',  'c'])

	print 'Top View: ',
	btree.top_view()
	print

	l = []
	btree.top_view(collate_fn, lst=l)
	assert (l == ['+', 'a',  '*', 'c'])

	print 'Top View L-R: ',
	btree.top_view_LR()
	print

	l = []
	btree.top_view_LR(collate_fn, lst=l)
	assert (l == ['a', '+',  '*', 'c'])


	print 'Bottom View: ',
	btree.bottom_view()
	print

	l = []
	btree.bottom_view(collate_fn, lst=l)
	assert (l == ['a', 'b',  '*', 'c'])

	print 'Testcase TC1 passed!'
def basic_tests():
	# prefix equation tree : "+a*bc"
	'''
	     +
	   /   \	
      a     *
	      /   \
	     b     c
	'''		 

	root = Node("+")
	lnode = Node("a")
	rnode = Node("*")
	root.setChildren(lnode, rnode)

	rlnode = Node("b")
	rrnode = Node("c")
	rnode.setChildren(rlnode, rrnode)

	btree = BinaryTree(root)

	assert(btree.height() == 3)
	assert btree.span() == 3
	assert btree.width() == 2

	'''
           1
         /   \
        3     2
       / \     \  
      5   3     9 
	'''
	root = Node("1")
	root.setChildren(Node("3"), Node("2"))
	root.left.setChildren(Node("5"), Node("3"))
	root.right.right = Node("9")
	btree2 = BinaryTree(root)
	assert(btree2.height() == 3)
	assert btree2.span() == 4
	assert btree2.width() == 3

	'''
           1
         /   \
        3     2
       / 
      5
	'''
	root = Node("1")
	root.setChildren(Node("3"), Node("2"))
	root.left.left = Node("5")
	btree3 = BinaryTree(root)
	assert(btree3.height() == 3)
	assert btree3.span() == 3
	assert btree3.width() == 2


	btree4 = BinaryTree(Node('blah'))
	assert(btree4.height() == 1)
	assert btree4.span() == 0
	assert btree4.width() == 1
def test_path_and_lca():
	'''
		 1
	   /   \    
	  2     3
	 /  \  /  \
	4    5 6   7
	'''      

	root = Node(1)
	lnode = Node(2)
	rnode = Node(3)
	root.setChildren(lnode, rnode)

	lnode.setChildren(Node(4), Node(5))
	rnode.setChildren(Node(6), Node(7))
	btree = BinaryTree(root)

	assert(btree.height() == 3)

	nodes =  btree.path_n(7)
	path = [1,3,7]
	i=0
	assert(len(nodes) == 3)
	for n in nodes:
		assert n.value == path[i]
		i += 1

	# find path using a node reference
	nodes =  btree.path_n(rnode)
	path = [1,3]
	i=0
	for n in nodes:
		assert n.value == path[i]
		i += 1

	assert(btree.path_n(8) == [])

	assert btree.path_1(7) == [1,3,7]
	assert btree.path_1(5) == [1,2,5]
	assert btree.path_1(6) == [1,3,6]
	assert btree.path_1(1) == [1]
	assert btree.path_1(2) == [1, 2]
	assert btree.path_1(9) == []

	assert btree.path_2(7) == [1,3,7]
	assert btree.path_2(5) == [1,2,5]
	assert btree.path_2(6) == [1,3,6]
	assert btree.path_2(1) == [1]
	assert btree.path_2(2) == [1, 2]
	assert btree.path_2(9) == []

	assert btree.path(2) == [1, 2]
	assert btree.path(9) == []


	# Test paths-based LCA
	n1 = rnode.left
	n2 = lnode.right
	assert n1.value == 6
	assert n2.value == 5
	assert btree.lca_p(n1, n2) == root

	assert btree.lca_p(rnode, lnode) == root
	assert btree.lca_p(rnode.right, rnode.left) == rnode
	assert btree.lca_p(lnode.right, lnode.left) == lnode
	assert btree.lca_p(lnode.left, rnode.right) == root

	assert btree.lca_p(rnode, 2) == root
	assert btree.lca_p(7, rnode.left) == rnode
	assert btree.lca_p(5, 4) == lnode
	assert btree.lca_p(4, 7) == root
	assert btree.lca_p(2, 4) == root.left
	assert btree.lca_p(4, 2) == root.left
	assert btree.lca_p(3, 7) == root.right
	assert btree.lca_p(7, 3) == root.right

	# Test efficient LCA that obviates the need for storing paths
	assert btree.lca(n1, n2) == root
	assert btree.lca(rnode, lnode) == root
	assert btree.lca(rnode.right, rnode.left) == rnode
	assert btree.lca(lnode.right, lnode.left) == lnode
	assert btree.lca(lnode.left, rnode.right) == root

	assert btree.lca(rnode, 2) == root
	assert btree.lca(4, 5) == root.left
	assert btree.lca(5, 4) == root.left
	assert btree.lca(7, rnode.left) == rnode
	assert btree.lca(5, 4) == lnode
	assert btree.lca(4, 7) == root
	assert btree.lca(2, 4) == root.left
	assert btree.lca(4, 2) == root.left
	assert btree.lca(3, 7) == root.right
	assert btree.lca(7, 3) == root.right