Write functions to implement recursive versions of preorder, inorder and postorder traversals of binary trees. Use stack to implement the recursion.
Q.) Write functions to implement recursive versions of preorder, inorder and postorder traversals of binary trees. Use stack to implement the recursion.
Subject: Data StructuresSure, let's start by understanding what these tree traversals are:
- Preorder Traversal: Visit the root first, then traverse the left subtree, and finally the right subtree.
- Inorder Traversal: Traverse the left subtree first, then visit the root, and finally the right subtree.
- Postorder Traversal: Traverse the left subtree first, then the right subtree, and finally visit the root.
Now, let's write the functions for these traversals using recursion and stack.
First, let's define the structure of a node in the binary tree:
class Node:
def __init__(self, key):
self.left = None
self.right = None
self.val = key
Now, let's write the functions for the traversals:
- Preorder Traversal:
def preorder(root):
if root:
# Stack to keep nodes
stack = []
stack.append(root)
while stack:
node = stack.pop()
print(node.val, end=" ")
# Push right and left children of the popped node to stack
if node.right:
stack.append(node.right)
if node.left:
stack.append(node.left)
- Inorder Traversal:
def inorder(root):
# Set current to root of binary tree
current = root
stack = [] # Initialize stack
while True:
# Reach the left most Node of the current Node
if current is not None:
# Place pointer to a tree node on the stack before traversing the node's left subtree
stack.append(current)
current = current.left
# BackTrack from the empty subtree and visit the node at the top of the stack; however, if the stack is empty, you are done
elif(stack):
current = stack.pop()
print(current.val, end=" ") # Python 3 printing
# We have visited the node and its left subtree. Now, it's right subtree's turn
current = current.right
else:
break
- Postorder Traversal:
def postorder(root):
if root is None:
return
stack1 = []
stack2 = []
# Push root to first stack
stack1.append(root)
# Run while first stack is not empty
while stack1:
# Pop an item from stack1 and push it to stack2
node = stack1.pop()
stack2.append(node)
# Push left and right children of popped item to stack1
if node.left:
stack1.append(node.left)
if node.right:
stack1.append(node.right)
# Print all elements of second stack
while stack2:
node = stack2.pop()
print(node.val, end=" ")
In these functions, we are using a stack to keep track of nodes. In the case of preorder traversal, we first visit the root, then its left subtree and finally its right subtree. For inorder traversal, we first visit the left subtree, then the root and finally the right subtree. For postorder traversal, we first visit the left subtree, then the right subtree and finally the root.
The time complexity for these functions is O(n), where n is the number of nodes in the tree, because we are visiting each node once. The space complexity is also O(n), because in the worst case, we might have to hold all nodes in the stack.