Skip to content

Commit

Permalink
Construct full binary tree from preorder and postorder traversal (keo…
Browse files Browse the repository at this point in the history
…n#736)

* Construct full binary tree from preorder and postorder

* Construct full binary tree from preorder and postorder

* Construct full binary tree from preorder and postorder

* Construct full binary tree from preorder and postorder

* Construct full binary tree from preorder and postorder

* added unit test to test_tree.py and changed to snake case to name cariables and functions

* added unit test to test_tree.py and changed to snake case to name cariables and functions

* added unit test to test_tree.py and changed to snake case to name cariables and functions
  • Loading branch information
ShimoniSinha2019H1030019G authored Nov 2, 2020
1 parent 422b1d1 commit a0cd48b
Show file tree
Hide file tree
Showing 4 changed files with 142 additions and 0 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -375,6 +375,7 @@ If you want to uninstall algorithms, it is as simple as:
- [b_tree](algorithms/tree/b_tree.py)
- [binary_tree_paths](algorithms/tree/binary_tree_paths.py)
- [bin_tree_to_list](algorithms/tree/bin_tree_to_list.py)
- [construct_tree_preorder_postorder](algorithms/tree/construct_tree_postorder_preorder.py)
- [deepest_left](algorithms/tree/deepest_left.py)
- [invert_tree](algorithms/tree/invert_tree.py)
- [is_balanced](algorithms/tree/is_balanced.py)
Expand Down
Empty file added algorithms/tree/__init__.py
Empty file.
111 changes: 111 additions & 0 deletions algorithms/tree/construct_tree_postorder_preorder.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
"""
Given two arrays representing preorder and postorder traversal of a full
binary tree, construct the binary tree and print the inorder traversal of the
tree.
A full binary tree has either 0 or 2 children.
Algorithm:
1. Assign the first element of preorder array as root of the tree.
2. Find the same element in the postorder array and divide the postorder
array into left and right subtree.
3. Repeat the above steps for all the elements and construct the tree.
Eg: pre[] = {1, 2, 4, 8, 9, 5, 3, 6, 7}
post[] = {8, 9, 4, 5, 2, 6, 7, 3, 1}
Tree:
1
/ \
2 3
/ \ / \
4 5 6 7
/ \
8 9
Output: 8 4 9 2 5 1 6 3 7
"""

class TreeNode:

def __init__(self, val, left = None, right = None):
self.val = val
self.left = left
self.right = right

pre_index = 0

def construct_tree_util(pre: list, post: list, low: int, high: int, size: int):
"""
Recursive function that constructs tree from preorder and postorder array.
preIndex is a global variable that keeps track of the index in preorder
array.
preorder and postorder array are represented are pre[] and post[] respectively.
low and high are the indices for the postorder array.
"""

global pre_index

if pre_index == -1:
pre_index = 0


#Base case
if(pre_index >= size or low > high):
return None

root = TreeNode(pre[pre_index])
pre_index += 1

#If only one element in the subarray return root
if(low == high or pre_index >= size):
return root

#Find the next element of pre[] in post[]
i = low
while i <= high:
if(pre[pre_index] == post[i]):
break

i += 1

#Use index of element present in postorder to divide postorder array
#to two parts: left subtree and right subtree
if(i <= high):
root.left = construct_tree_util(pre, post, low, i, size)
root.right = construct_tree_util(pre, post, i+1, high, size)

return root


def construct_tree(pre: list, post: list, size: int):
"""
Main Function that will construct the full binary tree from given preorder
and postorder array.
"""

global pre_index
root = construct_tree_util(pre, post, 0, size-1, size)

return print_inorder(root)



def print_inorder(root: TreeNode, result = None):
"""
Prints the tree constructed in inorder format
"""
if root is None:
return []
if result is None:
result = []

print_inorder(root.left, result)
result.append(root.val)
print_inorder(root.right, result)
return result

if __name__ == '__main__':
pre = [1, 2, 4, 5, 3, 6, 7]
post = [4, 5, 2, 6, 7, 3, 1]
size = len(pre)

result = construct_tree(pre, post, size)

print(result)
30 changes: 30 additions & 0 deletions tests/test_tree.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
)
from algorithms.tree.b_tree import BTree

from algorithms.tree import construct_tree_postorder_preorder as ctpp

import unittest


Expand Down Expand Up @@ -107,6 +109,34 @@ def test_deletion_odd_degree(self):
self.assertEqual(btree.root.keys, [])
self.assertEqual(btree.root.children, [])

class TestConstructTreePreorderPostorder(unittest.TestCase):
def test_construct_tree(self):

# Test 1
ctpp.pre_index = 0
pre1 = [1, 2, 4, 8, 9, 5, 3, 6, 7]
post1 = [8, 9, 4, 5, 2, 6, 7, 3, 1]
size1 = len(pre1)

self.assertEqual(ctpp.construct_tree(pre1, post1, size1), [8,4,9,2,5,1,6,3,7])

# Test 2
ctpp.pre_index = 0
pre2 = [1, 2, 4, 5, 3, 6, 7]
post2 = [4, 5, 2, 6, 7, 3, 1]
size2 = len(pre2)

self.assertEqual(ctpp.construct_tree(pre2, post2, size2), [4,2,5,1,6,3,7])

# Test 3
ctpp.pre_index = 0
pre3 = [12, 7, 16, 21, 5, 1, 9]
post3 = [16, 21, 7, 1, 9, 5, 12]
size3 = len(pre3)

self.assertEqual(ctpp.construct_tree(pre3, post3, size3), [16,7,21,12,1,5,9])



if __name__ == '__main__':
unittest.main()

0 comments on commit a0cd48b

Please sign in to comment.