# ---
# jupyter:
#   jupytext:
#     text_representation:
#       extension: .py
#       format_name: light
#       format_version: '1.5'
#       jupytext_version: 1.14.4
#   kernelspec:
#     display_name: Python 3
#     language: python
#     name: python3
# ---

# ### Printing a Tree:

# +
There are many ways to print the tree but we need to print it in some order.

1: 2,3
2: 4,5
4:
5:
6:


# -

# **Most of the problems in tree we solve it using recursion but 
# there are a very little problems in trees that are need to be solved using iteration. 

class BinaryTreeNode:
    def __init__(self, data):
        self.data = data
        self.left = None
        self.right = None   


# def printTree(root):
#     
#     if root.left is None and root.right is None:       # What if root is None?
#         print(root.data)                               # We need to take care of all these left and right
#         return
#     
#     elif root.left is None:
#         print(root.data)
#         printTree(root.right)
#     elif root.right is None:
#         print(root.data)
#         printTree(root.left)
#     

def printTree(root):
    if root == None:
        return
    print(root.data)
    printTree(root.left)
    printTree(root.right)


def printTreeDetailed(root):
    if root == None:
        return
    print(root.data, end = ": ")
    print("L", root.left.data, end = ",")
    print("R", root.right.data)
    printTreeDetailed(root.left)
    printTreeDetailed(root.right)


btn1 = BinaryTreeNode(1)
btn2 = BinaryTreeNode(4)
btn3 = BinaryTreeNode(5)

btn1.left = btn2
btn1.right = btn3

printTree(btn1)

# +
# This doesn't gives mcuh information about the tree. So, we're going to print the tree in detail

printTreeDetailed(btn1)


# -

# ### Here's how we fix the above error:

# +
# It's giving an error because 4's left is None and we're trying to print the data of None. So, Attribute Error
# To fix this we'll print the left child iff the root has left child and we do the same for the right child

def printTreeDetailed(root):
    if root == None:
        return
    print(root.data, end = ": ")
    if root.left != None:
        print("L", root.left.data, end = ",")
    if root.left != None:
        print("R", root.right.data, end = " ")
    print()
    printTreeDetailed(root.left)
    printTreeDetailed(root.right)



# -

printTreeDetailed(btn1)

# ### Now we check the same with a big tree: (The entire code at once):
#        We're trying to create the following tree

                  1
                 / \
                /   \
               /     \
              2       3
             / \     / 
            4   5   6


# +
class BinaryTreeNode():
    def __init__(self, data):
        self.data = data
        self.left = None
        self.right = None

# First we create nodes of the binary tree
bt1 = BinaryTreeNode(1)
bt2 = BinaryTreeNode(2)
bt3 = BinaryTreeNode(3)
bt4 = BinaryTreeNode(4)
bt5 = BinaryTreeNode(5)
bt6 = BinaryTreeNode(6)

# Latter we connect them 
bt1.left = bt2       # Here I'm assigning nodes in level order. So, don't get confused
bt1.right = bt3

bt2.left = bt4       # Level 2 
bt2.right = bt5
bt3.left = bt6

# Not required to assight left and right of leaf nodes as None because by default they'll
# be None at the time of Node Creation (Refer Node Creation)

def printTreeDetailed(root):
    if root == None:
        return
    print(root.data, end = ":")
    
    if root.left is not None:
        print("L", root.left.data, end = ",")
    
    if root.right is not None:
        print("R", root.right.data, end = " ")
        
    print()
    printTreeDetailed(root.left)          # Doing the same for the root's left sub tree
    printTreeDetailed(root.right)         # Doing the same for the root's right sub tree

printTreeDetailed(bt1)
# Now, with the below output, you can easitly construct a tree and it's understandable. 

StarcoderdataJupyterScriptsDedupFiltered