TheAlgorithms-Python
305 строк · 8.8 Кб
1"""
2This is pure Python implementation of tree traversal algorithms
3"""
4
5from __future__ import annotations6
7import queue8
9
10class TreeNode:11def __init__(self, data):12self.data = data13self.right = None14self.left = None15
16
17def build_tree() -> TreeNode:18print("\n********Press N to stop entering at any point of time********\n")19check = input("Enter the value of the root node: ").strip().lower()20q: queue.Queue = queue.Queue()21tree_node = TreeNode(int(check))22q.put(tree_node)23while not q.empty():24node_found = q.get()25msg = f"Enter the left node of {node_found.data}: "26check = input(msg).strip().lower() or "n"27if check == "n":28return tree_node29left_node = TreeNode(int(check))30node_found.left = left_node31q.put(left_node)32msg = f"Enter the right node of {node_found.data}: "33check = input(msg).strip().lower() or "n"34if check == "n":35return tree_node36right_node = TreeNode(int(check))37node_found.right = right_node38q.put(right_node)39raise40
41
42def pre_order(node: TreeNode) -> None:43"""44>>> root = TreeNode(1)
45>>> tree_node2 = TreeNode(2)
46>>> tree_node3 = TreeNode(3)
47>>> tree_node4 = TreeNode(4)
48>>> tree_node5 = TreeNode(5)
49>>> tree_node6 = TreeNode(6)
50>>> tree_node7 = TreeNode(7)
51>>> root.left, root.right = tree_node2, tree_node3
52>>> tree_node2.left, tree_node2.right = tree_node4 , tree_node5
53>>> tree_node3.left, tree_node3.right = tree_node6 , tree_node7
54>>> pre_order(root)
551,2,4,5,3,6,7,
56"""
57if not isinstance(node, TreeNode) or not node:58return59print(node.data, end=",")60pre_order(node.left)61pre_order(node.right)62
63
64def in_order(node: TreeNode) -> None:65"""66>>> root = TreeNode(1)
67>>> tree_node2 = TreeNode(2)
68>>> tree_node3 = TreeNode(3)
69>>> tree_node4 = TreeNode(4)
70>>> tree_node5 = TreeNode(5)
71>>> tree_node6 = TreeNode(6)
72>>> tree_node7 = TreeNode(7)
73>>> root.left, root.right = tree_node2, tree_node3
74>>> tree_node2.left, tree_node2.right = tree_node4 , tree_node5
75>>> tree_node3.left, tree_node3.right = tree_node6 , tree_node7
76>>> in_order(root)
774,2,5,1,6,3,7,
78"""
79if not isinstance(node, TreeNode) or not node:80return81in_order(node.left)82print(node.data, end=",")83in_order(node.right)84
85
86def post_order(node: TreeNode) -> None:87"""88>>> root = TreeNode(1)
89>>> tree_node2 = TreeNode(2)
90>>> tree_node3 = TreeNode(3)
91>>> tree_node4 = TreeNode(4)
92>>> tree_node5 = TreeNode(5)
93>>> tree_node6 = TreeNode(6)
94>>> tree_node7 = TreeNode(7)
95>>> root.left, root.right = tree_node2, tree_node3
96>>> tree_node2.left, tree_node2.right = tree_node4 , tree_node5
97>>> tree_node3.left, tree_node3.right = tree_node6 , tree_node7
98>>> post_order(root)
994,5,2,6,7,3,1,
100"""
101if not isinstance(node, TreeNode) or not node:102return103post_order(node.left)104post_order(node.right)105print(node.data, end=",")106
107
108def level_order(node: TreeNode) -> None:109"""110>>> root = TreeNode(1)
111>>> tree_node2 = TreeNode(2)
112>>> tree_node3 = TreeNode(3)
113>>> tree_node4 = TreeNode(4)
114>>> tree_node5 = TreeNode(5)
115>>> tree_node6 = TreeNode(6)
116>>> tree_node7 = TreeNode(7)
117>>> root.left, root.right = tree_node2, tree_node3
118>>> tree_node2.left, tree_node2.right = tree_node4 , tree_node5
119>>> tree_node3.left, tree_node3.right = tree_node6 , tree_node7
120>>> level_order(root)
1211,2,3,4,5,6,7,
122"""
123if not isinstance(node, TreeNode) or not node:124return125q: queue.Queue = queue.Queue()126q.put(node)127while not q.empty():128node_dequeued = q.get()129print(node_dequeued.data, end=",")130if node_dequeued.left:131q.put(node_dequeued.left)132if node_dequeued.right:133q.put(node_dequeued.right)134
135
136def level_order_actual(node: TreeNode) -> None:137"""138>>> root = TreeNode(1)
139>>> tree_node2 = TreeNode(2)
140>>> tree_node3 = TreeNode(3)
141>>> tree_node4 = TreeNode(4)
142>>> tree_node5 = TreeNode(5)
143>>> tree_node6 = TreeNode(6)
144>>> tree_node7 = TreeNode(7)
145>>> root.left, root.right = tree_node2, tree_node3
146>>> tree_node2.left, tree_node2.right = tree_node4 , tree_node5
147>>> tree_node3.left, tree_node3.right = tree_node6 , tree_node7
148>>> level_order_actual(root)
1491,
1502,3,
1514,5,6,7,
152"""
153if not isinstance(node, TreeNode) or not node:154return155q: queue.Queue = queue.Queue()156q.put(node)157while not q.empty():158list_ = []159while not q.empty():160node_dequeued = q.get()161print(node_dequeued.data, end=",")162if node_dequeued.left:163list_.append(node_dequeued.left)164if node_dequeued.right:165list_.append(node_dequeued.right)166print()167for node in list_:168q.put(node)169
170
171# iteration version
172def pre_order_iter(node: TreeNode) -> None:173"""174>>> root = TreeNode(1)
175>>> tree_node2 = TreeNode(2)
176>>> tree_node3 = TreeNode(3)
177>>> tree_node4 = TreeNode(4)
178>>> tree_node5 = TreeNode(5)
179>>> tree_node6 = TreeNode(6)
180>>> tree_node7 = TreeNode(7)
181>>> root.left, root.right = tree_node2, tree_node3
182>>> tree_node2.left, tree_node2.right = tree_node4 , tree_node5
183>>> tree_node3.left, tree_node3.right = tree_node6 , tree_node7
184>>> pre_order_iter(root)
1851,2,4,5,3,6,7,
186"""
187if not isinstance(node, TreeNode) or not node:188return189stack: list[TreeNode] = []190n = node191while n or stack:192while n: # start from root node, find its left child193print(n.data, end=",")194stack.append(n)195n = n.left196# end of while means current node doesn't have left child197n = stack.pop()198# start to traverse its right child199n = n.right200
201
202def in_order_iter(node: TreeNode) -> None:203"""204>>> root = TreeNode(1)
205>>> tree_node2 = TreeNode(2)
206>>> tree_node3 = TreeNode(3)
207>>> tree_node4 = TreeNode(4)
208>>> tree_node5 = TreeNode(5)
209>>> tree_node6 = TreeNode(6)
210>>> tree_node7 = TreeNode(7)
211>>> root.left, root.right = tree_node2, tree_node3
212>>> tree_node2.left, tree_node2.right = tree_node4 , tree_node5
213>>> tree_node3.left, tree_node3.right = tree_node6 , tree_node7
214>>> in_order_iter(root)
2154,2,5,1,6,3,7,
216"""
217if not isinstance(node, TreeNode) or not node:218return219stack: list[TreeNode] = []220n = node221while n or stack:222while n:223stack.append(n)224n = n.left225n = stack.pop()226print(n.data, end=",")227n = n.right228
229
230def post_order_iter(node: TreeNode) -> None:231"""232>>> root = TreeNode(1)
233>>> tree_node2 = TreeNode(2)
234>>> tree_node3 = TreeNode(3)
235>>> tree_node4 = TreeNode(4)
236>>> tree_node5 = TreeNode(5)
237>>> tree_node6 = TreeNode(6)
238>>> tree_node7 = TreeNode(7)
239>>> root.left, root.right = tree_node2, tree_node3
240>>> tree_node2.left, tree_node2.right = tree_node4 , tree_node5
241>>> tree_node3.left, tree_node3.right = tree_node6 , tree_node7
242>>> post_order_iter(root)
2434,5,2,6,7,3,1,
244"""
245if not isinstance(node, TreeNode) or not node:246return247stack1, stack2 = [], []248n = node249stack1.append(n)250while stack1: # to find the reversed order of post order, store it in stack2251n = stack1.pop()252if n.left:253stack1.append(n.left)254if n.right:255stack1.append(n.right)256stack2.append(n)257while stack2: # pop up from stack2 will be the post order258print(stack2.pop().data, end=",")259
260
261def prompt(s: str = "", width=50, char="*") -> str:262if not s:263return "\n" + width * char264left, extra = divmod(width - len(s) - 2, 2)265return f"{left * char} {s} {(left + extra) * char}"266
267
268if __name__ == "__main__":269import doctest270
271doctest.testmod()272print(prompt("Binary Tree Traversals"))273
274node: TreeNode = build_tree()275print(prompt("Pre Order Traversal"))276pre_order(node)277print(prompt() + "\n")278
279print(prompt("In Order Traversal"))280in_order(node)281print(prompt() + "\n")282
283print(prompt("Post Order Traversal"))284post_order(node)285print(prompt() + "\n")286
287print(prompt("Level Order Traversal"))288level_order(node)289print(prompt() + "\n")290
291print(prompt("Actual Level Order Traversal"))292level_order_actual(node)293print("*" * 50 + "\n")294
295print(prompt("Pre Order Traversal - Iteration Version"))296pre_order_iter(node)297print(prompt() + "\n")298
299print(prompt("In Order Traversal - Iteration Version"))300in_order_iter(node)301print(prompt() + "\n")302
303print(prompt("Post Order Traversal - Iteration Version"))304post_order_iter(node)305print(prompt())306