xxxxxxxxxx
A tree is a graph whose degree of node== # of it's children & is acyclic
Binary tree is a tree with each node having atmost 2 children.
2 ways to traverse each node once:
BFS - level wise
DFS - BY RECURSIVELY TRAVERSING ROOT,LEFT SUBTREE (L) & RIGHT SUBTREE (R)
NOTE: THERE ARE 3! WAYS OF DOING A DFS, BASED ON ORDER OF Root,L,R.
but only 3 are useful :
Root,L,R- preorder traversal
L,Root,R- inorder traversal
L,R,Root- postorder traversal
xxxxxxxxxx
<> Preorder Root -> Left -> Right
<> Inorder Left -> Root -> Right
<> Postorder Left -> Right -> Root
xxxxxxxxxx
/*
This is an implementation that collects the
values of the nodes of a binary tree by performing
an in-order traversal of the tree.
Let n be the number of binary tree nodes
Time complexity: O(n)
Space complexity: O(n)
*/
import java.util.List;
import java.util.ArrayList;
public class BTInOrderTraversal {
private BTNode BTRoot;
public BTInOrderTraversal() {
/*
* Create tree below:
* 1
* \
* 2
* /
* 3
*/
BTRoot = new BTNode(1, null, null);
BTNode rootRight = new BTNode(2, null, null);
BTRoot.right = rootRight;
BTNode rootRightLeft = new BTNode(3, null, null);
rootRight.left = rootRightLeft;
}
public static void main(String[] args) {
BTInOrderTraversal application = new BTInOrderTraversal();
List<Integer> values = application.inorderTraversal();
System.out.println(values); // [1, 3, 2]
}
// Perform in-order traversal through the tree.
public List<Integer> inorderTraversal() {
List<Integer> list = new ArrayList<>();
populateList(BTRoot, list);
return list;
}
// Helper method to populate list by performing
// in-order traversal through the tree.
private void populateList(BTNode root, List<Integer> list) {
if (root == null) {
return;
}
if (root.left != null) {
populateList(root.left, list);
}
list.add(root.val);
if (root.right != null) {
populateList(root.right, list);
}
}
// Class representing a binary tree node
// with pointers to value, left, and right nodes
private class BTNode {
int val;
BTNode left;
BTNode right;
public BTNode(int val, BTNode left, BTNode right) {
this.val = val;
this.left = left;
this.right = right;
}
}
}
xxxxxxxxxx
class Node:
def __init__(self,data):
self.data = data
self.parent = None
self.left = None
self.right = None
def __repr__(self):
return repr(self.data)
def add_left(self,node):
self.left = node
if node is not None:
node.parent = self
def add_right(self,node):
self.right = node
if node is not None:
node.parent = self
'''
Example:
_2_
/ \
7 9
/ \ \
1 6 8
/ \ / \
5 10 3 4
'''
def create_tree():
two = Node(2)
seven = Node(7)
nine = Node(9)
two.add_left(seven)
two.add_right(nine)
one = Node(1)
six = Node(6)
seven.add_left(one)
seven.add_right(six)
five = Node(5)
ten = Node(10)
six.add_left(five)
six.add_right(ten)
eight = Node(8)
three = Node(3)
four = Node(4)
nine.add_right(eight)
eight.add_left(three)
eight.add_right(four)
# now return the root node
return two
def pre_order(node):
print(node)
if node.left:
pre_order(node.left)
if node.right:
pre_order(node.right)
def in_order(node):
if node.left:
in_order(node.left)
print(node)
if node.right:
in_order(node.right)
def post_order(node):
if node.left:
post_order(node.left)
if node.right:
post_order(node.right)
print(node)
if __name__ == "__main__":
root = create_tree()
print("\nPre-order traversal:")
pre_order(root)
print("\nIn-order traversal:")
in_order(root)
print("\nPost-order traversal:")
post_order(root)
xxxxxxxxxx
def postOrder(root):
if root:
postOrder(root.left)
postOrder(root.right)
print(root, end = " ")
xxxxxxxxxx
1. Right child of 1 exists.
Push 3 to stack. Push 1 to stack. Move to left child.
Stack: 3, 1
2. Right child of 2 exists.
Push 5 to stack. Push 2 to stack. Move to left child.
Stack: 3, 1, 5, 2
3. Right child of 4 doesn't exist. '
Push 4 to stack. Move to left child.
Stack: 3, 1, 5, 2, 4
4. Current node is NULL.
Pop 4 from stack. Right child of 4 doesn't exist.
Print 4. Set current node to NULL.
Stack: 3, 1, 5, 2
5. Current node is NULL.
Pop 2 from stack. Since right child of 2 equals stack top element,
pop 5 from stack. Now push 2 to stack.
Move current node to right child of 2 i.e. 5
Stack: 3, 1, 2
6. Right child of 5 doesn't exist. Push 5 to stack. Move to left child.
Stack: 3, 1, 2, 5
7. Current node is NULL. Pop 5 from stack. Right child of 5 doesn't exist.
Print 5. Set current node to NULL.
Stack: 3, 1, 2
8. Current node is NULL. Pop 2 from stack.
Right child of 2 is not equal to stack top element.
Print 2. Set current node to NULL.
Stack: 3, 1
9. Current node is NULL. Pop 1 from stack.
Since right child of 1 equals stack top element, pop 3 from stack.
Now push 1 to stack. Move current node to right child of 1 i.e. 3
Stack: 1
10. Repeat the same as above steps and Print 6, 7 and 3.
Pop 1 and Print 1.
xxxxxxxxxx
Inorder Traversal using Stack:
As we already know, recursion can also be implemented using stack. Here also we can use a stack to perform inorder traversal of a Binary Tree. Below is the algorithm for traversing a binary tree using stack.
Create an empty stack (say S).
Initialize the current node as root.
Push the current node to S and set current = current->left until current is NULL
If current is NULL and the stack is not empty then:
Pop the top item from the stack.
Print the popped item and set current = popped_item->right
Go to step 3.
xxxxxxxxxx
Following is a simple stack based iterative process to print Preorder traversal.
Create an empty stack nodeStack and push root node to stack.
Do the following while nodeStack is not empty.
Pop an item from the stack and print it.
Push right child of a popped item to stack
Push left child of a popped item to stack
The right child is pushed before the left child to make sure that the left subtree is processed first.
xxxxxxxxxx
<> Preorder Root -> Left -> Right
<> Inorder Left -> Root -> Right
<> Postorder Left -> Right -> Root
xxxxxxxxxx
def inOrder(root):
if root:
inOrder(root.left)
print(root, end = " ")
inOrder(root.right)