https en wikipedia orgwikitreetraversal tree node1 tree left node2 tree right node3 tree left left node4 tree left right node5 return tree def preorderroot node none generatorint none none if not root return yield root data yield from preorderroot left yield from preorderroot right def postorderroot node none generatorint none none if not root return yield from postorderroot left yield from postorderroot right yield root data def inorderroot node none generatorint none none if not root return yield from inorderroot left yield root data yield from inorderroot right def reverseinorderroot node none generatorint none none if not root return yield from reverseinorderroot right yield root data yield from reverseinorderroot left def heightroot node none int return maxheightroot left heightroot right 1 if root else 0 def levelorderroot node none generatorint none none if root is none return processqueue dequeroot while processqueue node processqueue popleft yield node data if node left processqueue appendnode left if node right processqueue appendnode right def getnodesfromlefttoright root node none level int generatorint none none def populateoutputroot node none level int generatorint none none if not root return if level 1 yield root data elif level 1 yield from populateoutputroot left level 1 yield from populateoutputroot right level 1 yield from populateoutputroot level def getnodesfromrighttoleft root node none level int generatorint none none def populateoutputroot node none level int generatorint none none if root is none return if level 1 yield root data elif level 1 yield from populateoutputroot right level 1 yield from populateoutputroot left level 1 yield from populateoutputroot level def zigzagroot node none generatorint none none if root is none return flag 0 heighttree heightroot for h in range1 heighttree 1 if not flag yield from getnodesfromlefttorightroot h flag 1 else yield from getnodesfromrighttoleftroot h flag 0 def main none main function for testing create binary tree root maketree all traversals of the binary are as follows printfinorder traversal listinorderroot printfreverse inorder traversal listreverseinorderroot printfpreorder traversal listpreorderroot printfpostorder traversal listpostorderroot n printfheight of tree heightroot n printcomplete level order traversal printflistlevelorderroot n printlevelwise order traversal for level in range1 heightroot 1 printflevel level listgetnodesfromlefttorightroot levellevel printnzigzag order traversal printflistzigzagroot if name main import doctest doctest testmod main https en wikipedia org wiki tree_traversal the below tree 1 2 3 4 5 pre order traversal visits root node left subtree right subtree list preorder make_tree 1 2 4 5 3 post order traversal visits left subtree right subtree root node list postorder make_tree 4 5 2 3 1 in order traversal visits left subtree root node right subtree list inorder make_tree 4 2 5 1 3 reverse in order traversal visits right subtree root node left subtree list reverse_inorder make_tree 3 1 5 2 4 recursive function for calculating the height of the binary tree height none 0 height make_tree 3 returns a list of nodes value from a whole binary tree in level order traverse level order traverse visit nodes of the tree level by level returns a list of nodes value from a particular level left to right direction of the binary tree returns a list of nodes value from a particular level right to left direction of the binary tree zigzag traverse returns a list of nodes value from left to right and right to left alternatively main function for testing create binary tree all traversals of the binary are as follows
from __future__ import annotations

from collections import deque
from collections.abc import Generator
from dataclasses import dataclass



@dataclass
class Node:
    data: int
    left: Node | None = None
    right: Node | None = None


def make_tree() -> Node | None:
    r
    tree = Node(1)
    tree.left = Node(2)
    tree.right = Node(3)
    tree.left.left = Node(4)
    tree.left.right = Node(5)
    return tree


def preorder(root: Node | None) -> Generator[int, None, None]:
    
    if not root:
        return
    yield root.data
    yield from preorder(root.left)
    yield from preorder(root.right)


def postorder(root: Node | None) -> Generator[int, None, None]:
    
    if not root:
        return
    yield from postorder(root.left)
    yield from postorder(root.right)
    yield root.data


def inorder(root: Node | None) -> Generator[int, None, None]:
    
    if not root:
        return
    yield from inorder(root.left)
    yield root.data
    yield from inorder(root.right)


def reverse_inorder(root: Node | None) -> Generator[int, None, None]:
    
    if not root:
        return
    yield from reverse_inorder(root.right)
    yield root.data
    yield from reverse_inorder(root.left)


def height(root: Node | None) -> int:
    
    return (max(height(root.left), height(root.right)) + 1) if root else 0


def level_order(root: Node | None) -> Generator[int, None, None]:
    

    if root is None:
        return

    process_queue = deque([root])

    while process_queue:
        node = process_queue.popleft()
        yield node.data

        if node.left:
            process_queue.append(node.left)
        if node.right:
            process_queue.append(node.right)


def get_nodes_from_left_to_right(
    root: Node | None, level: int
) -> Generator[int, None, None]:
    

    def populate_output(root: Node | None, level: int) -> Generator[int, None, None]:
        if not root:
            return
        if level == 1:
            yield root.data
        elif level > 1:
            yield from populate_output(root.left, level - 1)
            yield from populate_output(root.right, level - 1)

    yield from populate_output(root, level)


def get_nodes_from_right_to_left(
    root: Node | None, level: int
) -> Generator[int, None, None]:
    

    def populate_output(root: Node | None, level: int) -> Generator[int, None, None]:
        if root is None:
            return
        if level == 1:
            yield root.data
        elif level > 1:
            yield from populate_output(root.right, level - 1)
            yield from populate_output(root.left, level - 1)

    yield from populate_output(root, level)


def zigzag(root: Node | None) -> Generator[int, None, None]:
    
    if root is None:
        return

    flag = 0
    height_tree = height(root)

    for h in range(1, height_tree + 1):
        if not flag:
            yield from get_nodes_from_left_to_right(root, h)
            flag = 1
        else:
            yield from get_nodes_from_right_to_left(root, h)
            flag = 0


def main() -> None:  
    
    root = make_tree()

    
    print(f"In-order Traversal: {list(inorder(root))}")
    print(f"Reverse In-order Traversal: {list(reverse_inorder(root))}")
    print(f"Pre-order Traversal: {list(preorder(root))}")
    print(f"Post-order Traversal: {list(postorder(root))}", "\n")

    print(f"Height of Tree: {height(root)}", "\n")

    print("Complete Level Order Traversal: ")
    print(f"{list(level_order(root))} \n")

    print("Level-wise order Traversal: ")

    for level in range(1, height(root) + 1):
        print(f"Level {level}:", list(get_nodes_from_left_to_right(root, level=level)))

    print("\nZigZag order Traversal: ")
    print(f"{list(zigzag(root))}")


if __name__ == "__main__":
    import doctest

    doctest.testmod()
    main()