11# https://en.wikipedia.org/wiki/Tree_traversal
22from __future__ import annotations
33
4+ from collections import deque
45from dataclasses import dataclass
6+ from typing import Any , Sequence
57
68
79@dataclass
@@ -11,11 +13,11 @@ class Node:
1113 right : Node | None = None
1214
1315
14- def make_tree () -> Node :
16+ def make_tree () -> Node | None :
1517 return Node (1 , Node (2 , Node (4 ), Node (5 )), Node (3 ))
1618
1719
18- def preorder (root : Node ) :
20+ def preorder (root : Node | None ) -> list [ int ] :
1921 """
2022 Pre-order traversal visits root node, left subtree, right subtree.
2123 >>> preorder(make_tree())
@@ -24,7 +26,7 @@ def preorder(root: Node):
2426 return [root .data ] + preorder (root .left ) + preorder (root .right ) if root else []
2527
2628
27- def postorder (root : Node ) :
29+ def postorder (root : Node | None ) -> list [ int ] :
2830 """
2931 Post-order traversal visits left subtree, right subtree, root node.
3032 >>> postorder(make_tree())
@@ -33,7 +35,7 @@ def postorder(root: Node):
3335 return postorder (root .left ) + postorder (root .right ) + [root .data ] if root else []
3436
3537
36- def inorder (root : Node ) :
38+ def inorder (root : Node | None ) -> list [ int ] :
3739 """
3840 In-order traversal visits left subtree, root node, right subtree.
3941 >>> inorder(make_tree())
@@ -42,7 +44,7 @@ def inorder(root: Node):
4244 return inorder (root .left ) + [root .data ] + inorder (root .right ) if root else []
4345
4446
45- def height (root : Node ) :
47+ def height (root : Node | None ) -> int :
4648 """
4749 Recursive function for calculating the height of the binary tree.
4850 >>> height(None)
@@ -53,99 +55,123 @@ def height(root: Node):
5355 return (max (height (root .left ), height (root .right )) + 1 ) if root else 0
5456
5557
56- def level_order_1 (root : Node ) :
58+ def level_order (root : Node | None ) -> Sequence [ Node | None ] :
5759 """
58- Print whole binary tree in Level Order Traverse.
60+ Returns a list of nodes value from a whole binary tree in Level Order Traverse.
5961 Level Order traverse: Visit nodes of the tree level-by-level.
6062 """
61- if not root :
62- return
63- temp = root
64- que = [temp ]
65- while len (que ) > 0 :
66- print (que [0 ].data , end = " " )
67- temp = que .pop (0 )
68- if temp .left :
69- que .append (temp .left )
70- if temp .right :
71- que .append (temp .right )
72- return que
63+ output : list [Any ] = []
7364
65+ if root is None :
66+ return output
7467
75- def level_order_2 (root : Node , level : int ):
76- """
77- Level-wise traversal: Print all nodes present at the given level of the binary tree
78- """
79- if not root :
80- return root
81- if level == 1 :
82- print (root .data , end = " " )
83- elif level > 1 :
84- level_order_2 (root .left , level - 1 )
85- level_order_2 (root .right , level - 1 )
68+ process_queue = deque ([root ])
69+
70+ while process_queue :
71+ node = process_queue .popleft ()
72+ output .append (node .data )
8673
74+ if node .left :
75+ process_queue .append (node .left )
76+ if node .right :
77+ process_queue .append (node .right )
78+ return output
8779
88- def print_left_to_right (root : Node , level : int ):
80+
81+ def get_nodes_from_left_to_right (
82+ root : Node | None , level : int
83+ ) -> Sequence [Node | None ]:
8984 """
90- Print elements on particular level from left to right direction of the binary tree.
85+ Returns a list of nodes value from a particular level:
86+ Left to right direction of the binary tree.
9187 """
92- if not root :
93- return
94- if level == 1 :
95- print (root .data , end = " " )
96- elif level > 1 :
97- print_left_to_right (root .left , level - 1 )
98- print_left_to_right (root .right , level - 1 )
88+ output : list [Any ] = []
89+
90+ def populate_output (root : Node | None , level : int ) -> None :
91+ if not root :
92+ return
93+ if level == 1 :
9994
95+ output .append (root .data )
96+ elif level > 1 :
97+ populate_output (root .left , level - 1 )
98+ populate_output (root .right , level - 1 )
10099
101- def print_right_to_left (root : Node , level : int ):
100+ populate_output (root , level )
101+ return output
102+
103+
104+ def get_nodes_from_right_to_left (
105+ root : Node | None , level : int
106+ ) -> Sequence [Node | None ]:
102107 """
103- Print elements on particular level from right to left direction of the binary tree.
108+ Returns a list of nodes value from a particular level:
109+ Right to left direction of the binary tree.
104110 """
105- if not root :
106- return
107- if level == 1 :
108- print (root .data , end = " " )
109- elif level > 1 :
110- print_right_to_left (root .right , level - 1 )
111- print_right_to_left (root .left , level - 1 )
111+ output : list [Any ] = []
112+
113+ def populate_output (root : Node | None , level : int ) -> None :
114+ if root is None :
115+ return
116+ if level == 1 :
117+ output .append (root .data )
118+ elif level > 1 :
119+ populate_output (root .right , level - 1 )
120+ populate_output (root .left , level - 1 )
112121
122+ populate_output (root , level )
123+ return output
113124
114- def zigzag (root : Node ):
125+
126+ def zigzag (root : Node | None ) -> Sequence [Node | None ] | list [Any ]:
115127 """
116- ZigZag traverse: Print node left to right and right to left, alternatively.
128+ ZigZag traverse:
129+ Returns a list of nodes value from left to right and right to left, alternatively.
117130 """
131+ if root is None :
132+ return []
133+
134+ output : list [Sequence [Node | None ]] = []
135+
118136 flag = 0
119137 height_tree = height (root )
138+
120139 for h in range (1 , height_tree + 1 ):
121- if flag == 0 :
122- print_left_to_right ( root , h )
140+ if not flag :
141+ output . append ( get_nodes_from_left_to_right ( root , h ) )
123142 flag = 1
124143 else :
125- print_right_to_left ( root , h )
144+ output . append ( get_nodes_from_right_to_left ( root , h ) )
126145 flag = 0
127146
147+ return output
148+
128149
129- def main (): # Main function for testing.
150+ def main () -> None : # Main function for testing.
130151 """
131152 Create binary tree.
132153 """
133154 root = make_tree ()
134155 """
135156 All Traversals of the binary are as follows:
136157 """
137- print (f" In-order Traversal is { inorder (root )} " )
138- print (f" Pre-order Traversal is { preorder (root )} " )
139- print (f"Post-order Traversal is { postorder (root )} " )
140- print (f"Height of Tree is { height (root )} " )
141- print ("Complete Level Order Traversal is : " )
142- level_order_1 (root )
143- print ("\n Level-wise order Traversal is : " )
144- for h in range (1 , height (root ) + 1 ):
145- level_order_2 (root , h )
146- print ("\n ZigZag order Traversal is : " )
147- zigzag (root )
148- print ()
158+
159+ print (f"In-order Traversal: { inorder (root )} " )
160+ print (f"Pre-order Traversal: { preorder (root )} " )
161+ print (f"Post-order Traversal: { postorder (root )} " , "\n " )
162+
163+ print (f"Height of Tree: { height (root )} " , "\n " )
164+
165+ print ("Complete Level Order Traversal: " )
166+ print (level_order (root ), "\n " )
167+
168+ print ("Level-wise order Traversal: " )
169+
170+ for level in range (1 , height (root ) + 1 ):
171+ print (f"Level { level } :" , get_nodes_from_left_to_right (root , level = level ))
172+
173+ print ("\n ZigZag order Traversal: " )
174+ print (zigzag (root ))
149175
150176
151177if __name__ == "__main__" :
0 commit comments