Golang Program Level Order Traversal of Binary Tree


In programming, there are different data structures to store data. There are two different types of data structures linear and non −linear. Array, stack, queue, and linked list are linear data structures. Binary trees, trie, etc are non − linear data structures. In this article, we are going to explore level order traversal on one of the non − linear data structures i.e. binary tree.

Level Order Traversal

In level order traversal, of a binary tree we start from the root node and then traverse the children nodes and move to the children of children nodes. In this way, we go to the last level and complete the level order traversal. To implement this we use the Breadth − first search algorithm in which we use queue data structures.

For example, in the above tree

Level 1: Traverse root node 1

Level 2: Traverse node 2, then node 3, and node 4 in the end.

Level 3: Traverse node 5, then node 6, and node 7 in the end.

Algorithm

Step 1: import "fmt" − Import fmt library

Step 2: type TreeNode struct { Val int Left *TreeNode Right *TreeNode } − Create a structure for a tree node that has an integer value to store node data and two tree node type pointer value.

Step 3: Start the main function

  • root : = TreeNode{0, nil, nil} − Create a variable for the root node of the type tree node.

  • Call function CreateBinaryTree(&root) to create complete binary tree.

  • levelOrder : = LevelOrderTraversal(&root) − call function to perform level order traversal by passing reference to the root node.

  • Print the array returned by the level order traversal function.

Step 4: Level order traversal function.

  • func LevelOrderTraversal(root *TreeNode) []int {} − Declaring a function with TreeNode type variable as an argument and integer array as return type.

  • if root == nil { return []int{} } − Checking if the root is nil or not if yes then returning an empty array.

  • var q Queue − Creating queue to implement Breadth First Search algorithm.

  • var levelOrder []int − creating an array to store elements level order during traversing the array in level order

  • Apply Breadth's first search algorithm and in the end return the array.

Example

In this code, we have implemented a queue data structure and its functions as well as currently there is no pre − build library for queues in Golang.

package main

import "fmt"

type Queue struct {
    List [](*TreeNode)
}

type TreeNode struct {
    Val   int
    Left  *TreeNode
    Right *TreeNode
}

// function to add an element in the queue
func (q *Queue) Enqueue(element *TreeNode) {
    q.List = append(q.List, element)
}

// function to delete elements in the queue
func (q *Queue) Dequeue() *TreeNode {
    if q.isEmpty() {
        fmt.Println("Queue is empty.")
        return nil
    }
    element := q.List[0]
    q.List = q.List[1:]

    return element
}

// function checks that queue is empty or not
func (q *Queue) isEmpty() bool {
    return len(q.List) == 0
}

// function to find the length of the queue
func (q *Queue) size() int {
    return len(q.List)
}

// creating binary tree
func CreateBinaryTree(root *TreeNode) {
    n1 := TreeNode{1, nil, nil}
    n2 := TreeNode{2, nil, nil}
    root.Left = &n1
    root.Right = &n2

    n3 := TreeNode{3, nil, nil}
    n4 := TreeNode{4, nil, nil}
    n1.Left = &n3
    n1.Right = &n4

    n5 := TreeNode{5, nil, nil}
    n6 := TreeNode{6, nil, nil}
    n2.Left = &n5
    n2.Right = &n6
}

// level order traversal of a function with root node as argument
// and returns the right-view elements in the array
func LevelOrderTraversal(root *TreeNode) []int {
    // returning empty array if the tree is empty
    if root == nil {
        return []int{}
    }

    // creating variable for queue
    var q Queue

    // creating array to store right side element
    var levelOrder []int

    // enqueue root address in the queue
    q.Enqueue(root)
    q.Enqueue(nil)

    // breadth-first search over the tree
    for q.size() > 1 {
        currNode := q.Dequeue()
        if currNode == nil {
            q.Enqueue(nil)
            levelOrder = append(levelOrder, -1)
            continue
        }
        levelOrder = append(levelOrder, currNode.Val)
        if currNode.Left != nil {
            q.Enqueue(currNode.Left)
        }
        if currNode.Right != nil {
            q.Enqueue(currNode.Right)
        }

    }

    return levelOrder
}

func main() {
    fmt.Println("Golang program to find the level order traversal of a binary tree.")

    // creating root node of binary tree
    root := TreeNode{0, nil, nil}
    // calling CreateBinaryTree function to create a complete binary tree
    CreateBinaryTree(&root)

    // calling LevelOrderTraversal function
    levelOrder := LevelOrderTraversal(&root)

    // print elements of binary tree in level order
    for i := 0; i < len(levelOrder); i++ {
        if levelOrder[i] == -1 {
            fmt.Println()
            continue
        }
        fmt.Print(levelOrder[i], " ")
    }
    fmt.Println()
}

Output

Golang program to find the level order traversal of a binary tree.
0 
1 2 
3 4 5 6

Conclusion

In this way, we implemented level order traversal on a tree using the Breadth First search algorithm. There are other traversing algorithms on a tree such as inorder, preorder, and post − order traversal. The time complexity of this approach is O(V + E) where V and E are the no. of vertices and no. of edges in the graph. We can use the Depth First search algorithm also to find the level order traversal of a tree. To learn more about Golang you can explore these tutorials.

Updated on: 10-Jul-2023

182 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements