1
1
# https://en.wikipedia.org/wiki/Tree_traversal
2
2
from __future__ import annotations
3
3
4
+ from collections import deque
4
5
from dataclasses import dataclass
6
+ from typing import Any , Sequence
5
7
6
8
7
9
@dataclass
@@ -11,11 +13,11 @@ class Node:
11
13
right : Node | None = None
12
14
13
15
14
- def make_tree () -> Node :
16
+ def make_tree () -> Node | None :
15
17
return Node (1 , Node (2 , Node (4 ), Node (5 )), Node (3 ))
16
18
17
19
18
- def preorder (root : Node ) :
20
+ def preorder (root : Node | None ) -> list [ int ] :
19
21
"""
20
22
Pre-order traversal visits root node, left subtree, right subtree.
21
23
>>> preorder(make_tree())
@@ -24,7 +26,7 @@ def preorder(root: Node):
24
26
return [root .data ] + preorder (root .left ) + preorder (root .right ) if root else []
25
27
26
28
27
- def postorder (root : Node ) :
29
+ def postorder (root : Node | None ) -> list [ int ] :
28
30
"""
29
31
Post-order traversal visits left subtree, right subtree, root node.
30
32
>>> postorder(make_tree())
@@ -33,7 +35,7 @@ def postorder(root: Node):
33
35
return postorder (root .left ) + postorder (root .right ) + [root .data ] if root else []
34
36
35
37
36
- def inorder (root : Node ) :
38
+ def inorder (root : Node | None ) -> list [ int ] :
37
39
"""
38
40
In-order traversal visits left subtree, root node, right subtree.
39
41
>>> inorder(make_tree())
@@ -42,7 +44,7 @@ def inorder(root: Node):
42
44
return inorder (root .left ) + [root .data ] + inorder (root .right ) if root else []
43
45
44
46
45
- def height (root : Node ) :
47
+ def height (root : Node | None ) -> int :
46
48
"""
47
49
Recursive function for calculating the height of the binary tree.
48
50
>>> height(None)
@@ -53,99 +55,123 @@ def height(root: Node):
53
55
return (max (height (root .left ), height (root .right )) + 1 ) if root else 0
54
56
55
57
56
- def level_order_1 (root : Node ) :
58
+ def level_order (root : Node | None ) -> Sequence [ Node | None ] :
57
59
"""
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.
59
61
Level Order traverse: Visit nodes of the tree level-by-level.
60
62
"""
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 ] = []
73
64
65
+ if root is None :
66
+ return output
74
67
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 )
86
73
74
+ if node .left :
75
+ process_queue .append (node .left )
76
+ if node .right :
77
+ process_queue .append (node .right )
78
+ return output
87
79
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 ]:
89
84
"""
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.
91
87
"""
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 :
99
94
95
+ output .append (root .data )
96
+ elif level > 1 :
97
+ populate_output (root .left , level - 1 )
98
+ populate_output (root .right , level - 1 )
100
99
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 ]:
102
107
"""
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.
104
110
"""
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 )
112
121
122
+ populate_output (root , level )
123
+ return output
113
124
114
- def zigzag (root : Node ):
125
+
126
+ def zigzag (root : Node | None ) -> Sequence [Node | None ] | list [Any ]:
115
127
"""
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.
117
130
"""
131
+ if root is None :
132
+ return []
133
+
134
+ output : list [Sequence [Node | None ]] = []
135
+
118
136
flag = 0
119
137
height_tree = height (root )
138
+
120
139
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 ) )
123
142
flag = 1
124
143
else :
125
- print_right_to_left ( root , h )
144
+ output . append ( get_nodes_from_right_to_left ( root , h ) )
126
145
flag = 0
127
146
147
+ return output
148
+
128
149
129
- def main (): # Main function for testing.
150
+ def main () -> None : # Main function for testing.
130
151
"""
131
152
Create binary tree.
132
153
"""
133
154
root = make_tree ()
134
155
"""
135
156
All Traversals of the binary are as follows:
136
157
"""
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 ))
149
175
150
176
151
177
if __name__ == "__main__" :
0 commit comments