×

Zigzag Traversal of Binary Tree in Java

In this article, you will be acknowledged about the zigzag traversal of binary tree in java and the approaches or ways in which the zigzag traversal can be done.

Zigzag Traversal

A binary tree is traversed in a zigzag pattern, which means that for each node at the top level, we move from left to right, and for the node at the next level, we move from right to left, and on and on. Be aware that while going to the next level requires going from left to right, the top level allows us to go from right to left rather than left to right. The crucial thing to keep in mind when performing a zigzag traverse of just a binary tree in Java that each level's traversal direction is the opposite of the level before it.

Zigzag Traversal of Binary Tree in Java

In the above binary tree with the given nodes, the two types of zigzag traversal path is

Right Traversal: 1 3 2 8 7 6 5 4

Left Traversal: 1 2 3 4 5 6 7 8

There are 4 ways that can achieve zigzag traversal in a simple binary tree. They are

  • Making use of Two Stacks
  • With Deque
  • Leveraging Recursion
  • Stack and Queue utilization

Making use of two stacks

Two stacks can be used to traverse a binary tree in a zigzag pattern. You should consider the first stack to be actual level stack and also the second stack to be the next level stack. In order to obtain information on the current level order, a variable is also necessary. We actually pop nodes out of actual level stack and show their values. When traversing the actual level order from left to right, we push the level's left child to the next level stack first, followed by the level's right child. We are aware that a stack operates according to the Last In First Out (LIFO) rule.

As a result, the sequence of traversing will be reversed the next time nodes are taken off of the nextlevel stack. Similar to how we move the right child of a current node before the left child while traversing from right to left. Keep in mind that we must switch the stacks once each level ends (which occurs when all of that level's nodes have been explored); that is, the next-level stack becomes the current-level stack, and vice versa.

Let us understand it with an example program

File name: Zigzag1.java

import java.util.*;  
  class TreeNode   
{  
int val;  
  
TreeNode left, right;  
  
public TreeNode(int i)  
{  
val = i;  
right = left = null;  
}  
}  
class BTZigZag   
{  
TreeNode r;  
//method that shows the zigzag traversal in a binary tree 
void displayZigZagTraversal()   
{  
if (r == null)   
{  
return;  
}  
//Initializing the two stacks  
Stack<TreeNode> currLevel = new Stack<TreeNode>();  
Stack<TreeNode> nextLevel = new Stack<TreeNode>();  
currLevel.push(r);  
boolean LtoR = true;  
while (!currLevel.isEmpty())   
{  
//The node has been removed from the current level   
TreeNode currNode = currLevel.pop();  
System.out.print(currNode.val + " ");  
if (LtoR)   
{  
if (currNode.left != null)   
{  
nextLevel.push(currNode.left);  
}  
if (currNode.right != null)   
{  
nextLevel.push(currNode.right);  
}  
}  
else   
{  
if (currNode.right != null)   
{  
nextLevel.push(currNode.right);  
}  
if (currNode.left != null)   
{  
nextLevel.push(currNode.left);  
}  
}  
if (currLevel.isEmpty())   
{  
// toggle the value of LtoR  
LtoR = !LtoR;  
Stack<TreeNode> stk = currLevel;  
currLevel = nextLevel;  
nextLevel = stk;  
}  
}  
}  
}  
public class ZigZag1 
{  
// main method  
public static void main(String[] args)  
{  
BTZigZag   
BTZigZag  tree = new BTZigZag ();  
//the root node
tree.r = new TreeNode(10);  
//The other nodes of the tree are
tree.r.left = new TreeNode(6);  
tree.r.right = new TreeNode(15);  
tree.r.left.left = new TreeNode(5);  
tree.r.left.right = new TreeNode(8);  
tree.r.right.left = new TreeNode(11);  
tree.r.right.right = new TreeNode(23);  
tree.r.left.left.left = new TreeNode(12);  
tree.r.left.left.right = new TreeNode(16);  
tree.r.left.right.left = new TreeNode(9);  
tree.r.left.right.right = new TreeNode(19);  
tree.r.right.left.left = new TreeNode(17);  
tree.r.right.left.right = new TreeNode(29);  
tree.r.right.right.left = new TreeNode(33);  
tree.r.right.right.right = new TreeNode(36);  
System.out.println("The nodes in the form of zigzag traversal : ");  
tree.displayZigZagTraversal();  
}  
}  

Output:

The nodes in the form of zigzag traversal 
10 6 15 5 8 11 23 12 16 9 19 17 29 33 36 

Time Complexity

The program contains just one while loop. As a result, the preceding programme has an O(n) time complexity, where n represents the total amount of nodes as in binary tree.  

Space Complexity

The code contains two stacks, each of which has an O(n) space complexity, where n corresponds to the total count of nodes in the binary tree. As a result, O(2 * n), which is equal to O in terms of exponential growth complexity (n).

Using Deque

A deque can be used to perform a binary tree's zigzag traverse as well. Choosing whether to do the pop operation from the front or the back side is a crucial consideration. Whether we move from right to left or from left to right is determined by the pop operation.

Let us understand it with an example program by using deque operation in queue.

File name: Zigzag2.java

import java.util.*;  
  class TreeNode   
{  
//holds the nodes values  
int val;  
//Linking all the nodes left nodes for the left and right nodes for the right nodes  
TreeNode left, right;  
//The initialization of class fields in done with help of a constructor  
public TreeNode(int i)  
{  
val = i;  
right = left = null;  
}  
}  
class BTreeZigZag1   
{  
TreeNode r;  
//This method helps in showing the zigzag traversal
public Vector<Integer> zigZagTraversal(TreeNode node)  
{  
Deque<TreeNode> dq = new LinkedList<TreeNode>();  
Vector<Integer> vec = new Vector<Integer>();  
dq.add(node);  
vec.add(node.val);  
TreeNode t;  
int lvl = 1;  
while (dq.size() > 0)   
{  
int n = dq.size();  
for (int j = 0; j < n; j++)   
{   
if (lvl % 2 == 0)   
{  
t = dq.peekLast();  
// deleting from the end 
dq.pollLast();  
}   
else   
{  
t = dq.peekFirst();  
dq.pollFirst();  
}
// The left child node is followed by the right child node when the level is odd
// The right child node is followed by the left child node when the level is even 
if (lvl % 2 != 0)   
{  
// The null nodes are found to be useless because they do not have any child nodes  
if (t.right != null)   
{  
dq.add(t.right);  
vec.add(t.right.val);  
}  
if (t.left != null)   
{  
dq.add(t.left);  
vec.add(t.left.val);  
}  
}  
else if (lvl % 2 == 0)  
{  
// // The null nodes are found to be useless because they do not have any child nodes
if (t.left != null)   
{  
dq.offerFirst(t.left);  
vec.add(t.left.val);  
}  
if (t.right != null)   
{  
dq.offerFirst(t.right);  
vec.add(t.right.val);  
}  
}  
}  
lvl = lvl + 1;  
}  
return vec;  
}  
}  
public class Zigzag2 
{ 
public static void main(String[] args)  
{  
BTZigZag1  tree = new BTZigZag1 ();  
tree.r = new TreeNode(10);    
tree.r.left = new TreeNode(6);  
tree.r.right = new TreeNode(15);  
tree.r.left.left = new TreeNode(5);  
tree.r.left.right = new TreeNode(8);  
tree.r.right.left = new TreeNode(11);  
tree.r.right.right = new TreeNode(23);  
tree.r.left.left.left = new TreeNode(12);  
tree.r.left.left.right = new TreeNode(16);  
tree.r.left.right.left = new TreeNode(9);  
tree.r.left.right.right = new TreeNode(19);  
tree.r.right.left.left = new TreeNode(17);  
tree.r.right.left.right = new TreeNode(29);  
tree.r.right.right.left = new TreeNode(33);  
tree.r.right.right.right = new TreeNode(36);  
System.out.println("The nodes in the form of zigzag traversal are: ");  
Vector<Integer> vec = tree.zigZagTraversal(tree.r);  
for (int j = 0; j < vec.size(); j++)   
{   
//printing the nodes in zigzag way 
System.out.print(vec.get(j) + " ");  
}  
}  
}  

Output

The nodes in the form of zigzag traversal are: 
10 15 6 23 11 8 5 36 33 29 16 19 9 16 12

Time complexity

The temporal complexity of the aforementioned code is O(n), in which n is the overall number of nodes in the binary tree, because we only visit each node once.

Space complexity

The largest size of the deque is O((n + 1) / 2), which has an asymptotic complexity equal to O(n), in which n refers to the overall number of nodes in the binary tree. Consider that the overall quantity of subtrees in a complete binary tree is (n + 1) / 2.

Using Leveraging Recursion

Recursion can also be used to traverse a binary tree in a zigzag pattern. The idea is to leveraging a binary tree's level order traversal in a novel way. A parameter whose value alternates between 0 and 1 will establish the path in which the traversing will proceed. Keep in mind that the variable's value modifies following the conclusion of each level's exploration.

Let us understand it with an example program by using the recursion methodology.

File name: Zigzag3.java

import java.util.*;  
class TreeNode   
{  
//For the value of node to be assigned 
int val;   
TreeNode left, right;  
//The class fields are created by the constructor  
public TreeNode(int i)  
{  
val = i;  
right = left = null;  
}  
}  
class BTreeZigZag2   
{  
TreeNode r;  
// The length of the tree is found by the recursion approach
//The important point is that all the levels of binary tree must be equal
public int heightOfBTree(TreeNode r)  
{  
if(r == null)  
{  
return 0;  
}  
int lh = heightOfBTree(r.left);  
int rh = heightOfBTree(r.right);  
return Math.max(lh + 1, rh + 1);  
}  
//This method displays the values of nodes from the right to left
public void displayRightToLeft(TreeNode r, int lvl)  
{  
if(r == null)  
{  
return;  
}  
if(lvl == 1)  
{  
System.out.print(r.val + " ") ;  
}  
else if(lvl > 1)  
{  
displayRightToLeft(r.right, lvl - 1);  
displayRightToLeft(r.left, lvl - 1);  
}  
}  
//This method displays the values of nodes from left to right  
public void displayLeftToRight(TreeNode r, int lvl)  
{   
if(r == null)  
{  
return;  
}    
if(lvl == 1)  
{  
System.out.print(r.val + " ");  
}  
//This is for managing the other nodes of the binary tree. 
else if(lvl > 1)  
{  
displayLeftToRight(r.left, lvl - 1);  
displayLeftToRight(r.right, lvl - 1);  
}  
}  
//This method displays the nodes of binary tree in zigzag traversal 
public void displayZigZagTraversal(TreeNode r)  
{  
int f = 0;  
//Length of the binary tree  
int ht = heightOfBTree(r);     
for(int j = 1; j <= ht; j++)  
{  
//The nodes values are displayed from right to left if the flag value is one  
if(f == 1)  
{  
displayRightToLeft(r, j);    
f = 1 - f;  
}  
// The nodes values are displayed from right to left if the flag value is one  
else if(f == 0)  
{  
displayLeftToRight(r, j);  
f = 1 - f;  
}  
}  
}  
}  
public class Zigzag3   
{  
public static void main(String[] argvs)  
{  
BTZigZag2 tree = new BTZigZag2();  
tree.r = new TreeNode(10);  
tree.r.left = new TreeNode(6);  
tree.r.right = new TreeNode(15);  
tree.r.left.left = new TreeNode(5);  
tree.r.left.right = new TreeNode(8);  
tree.r.right.left = new TreeNode(11);  
tree.r.right.right = new TreeNode(23);  
tree.r.left.left.left = new TreeNode(12);  
tree.r.left.left.right = new TreeNode(16);  
tree.r.left.right.left = new TreeNode(9);  
tree.r.left.right.right = new TreeNode(19);  
tree.r.right.left.left = new TreeNode(17);  
tree.r.right.left.right = new TreeNode(29);  
tree.r.right.right.left = new TreeNode(33);  
tree.r.right.right.right = new TreeNode(36);  
System.out.println("The nodes in the from of zigzag traversal are: ");  
tree.displayZigZagTraversal(tree.r);  
}  
}

Output

The nodes in the form of zigzag traversal are
10 15 6 23 11 8 5 36 33 29 16 19 9 16 12

Time Complexity

The preceding program's time complexity is O(n), where n is the overall number of nodes in the binary tree, and we are only visiting each node once. 

Space Complexity

The above-mentioned program's space complexity is O (n).

Using Stack and Queue utilization

This method involves traversing the level order, but not always in the same direction. When moving through a level from left to right, we add every node we come across to the array list maintain. Additionally, we keep the connections for the following level of the stack. We push the node out from stack which had been saved in the preceding stage while travelling from right to left. The array list retain contains the popped node. Finally, we deliver the array list maintain. Keep in mind that the method we employed for this approach's optimization was deque.

Let us understand it with an example program by using the recursion methodology.

File name: Zigzag4.java

import java.util.*;  
class TreeNode   
{    
int val;  
TreeNode left, right;  


public TreeNode(int i)  
{  
val = i;  
right = left = null;  
}  
}  
public class Zigzag4  
{  
TreeNode r = null;    
ArrayList<Integer> zigzagLevelOrderTraversal(TreeNode root)   
{   
ArrayList<Integer> keep = new ArrayList<Integer>();  
Queue<TreeNode> nodes = new LinkedList<TreeNode>();  
Stack<TreeNode> currentLevelNodes = new Stack<TreeNode>();  
nodes.add(root);  
int ltor = 1;  
while (!nodes.isEmpty())   
{  
if (ltor == 1)   
{  
int size = nodes.size();  
for (int j = 0; j < size; j++)   
{  
TreeNode currNode = nodes.peek();  
nodes.poll();  
keep.add(currNode.val);  
if (currNode.left != null)   
{  
nodes.add(currNode.left);  
currentLevelNodes.push(currNode.left);  
}  
if (currNode.right != null)   
{  
nodes.add(currNode.right);  
currentLevelNodes.push(currNode.right);  
}  
}  
}   
else   
{  
int size = nodes.size();  
for (int j = 0; j < size; j++)   
{  
TreeNode currentNode = nodes.peek();  
nodes.poll();  
keep.add(currentLevelNodes.peek().val);  
currentLevelNodes.pop();  
if (currentNode.left != null)   
{  
nodes.add(currentNode.left);  
}  
if (currentNode.right != null)   
{  
nodes.add(currentNode.right);  
}  
}  
}  
ltor = 1 - ltor;  
}  
return keep;  
}  
  
public static void main(String[] argvs)  
{  
Zigzag4 tree = new Zigzag4();  
tree.r = new TreeNode(10);  
tree.r.left = new TreeNode(6);  
tree.r.right = new TreeNode(15);  
tree.r.left.left = new TreeNode(5);  
tree.r.left.right = new TreeNode(8);  
tree.r.right.left = new TreeNode(11);  
tree.r.right.right = new TreeNode(23);  
tree.r.left.left.left = new TreeNode(12);  
tree.r.left.left.right = new TreeNode(16);  
tree.r.left.right.left = new TreeNode(9);  
tree.r.left.right.right = new TreeNode(19);  
tree.r.right.left.left = new TreeNode(17);  
tree.r.right.left.right = new TreeNode(29);  
tree.r.right.right.left = new TreeNode(33);  
tree.r.right.right.right = new TreeNode(36);  
System.out.println("The nodes in the form of zigzag traversal are: ");  
ArrayList<Integer> list = tree.zigzagLevelOrderTraversal(tree.r);  
for(int i = 0; i < list.size(); i++)  
{  
System.out.print(list.get(i) + " ");  
}  
}  
}  

Output

The nodes in the form of zigzag traversal are
10 15 6 23 11 8 5 36 33 29 16 19 9 16 12

Time complexity

The binary tree's total amount of nodes, n, corresponds to the time complexity, which is O(n).

Space complexity

The above-mentioned program's space complexity is O (n).


Related Topics

Java Integer class

The Integer class wraps a primitive int type value in an object. Its object contains only a single field whose type is int. Methods: The java.lang.Integer class provides several different methods for...

4 minutes read.

Jagged Array in Java

Prerequisite We must first understand what Arrays are and Multi-dimensional Arrays are before we can learn about Jagged arrays. Java Arrays: A collection of data types that are similar is called an...

5 minutes read.

Java Switch Keyword

In this article we are going to learn the concept of a java switch keyword. Generally, java case keyword is used with the switch statements or keyword.Switch keyword is implemented in...

3 minutes read.

Java Do While Loop

When we wish to test the exit condition at the end of the loop, we use a do-while loop. The do-while loop always executes its body at least once, because...

1 minute read.

Java Primitive Data Types

Primitive data types are the simplest data types in a programming language. They’re predefined in the language. The names of the primitive types are quite descriptive of the values that...

2 minutes read.

PriorityBlockingQueue Class in Java

What is the Queue? An abstract data structure like Stacks is a queue. A queue is open on both ends. Data is always pushed to one end, called enqueue, and removed...

4 minutes read.

How to compare two dates in different format in Java?

We need to compare two dates frequently when coding. Real-world examples include sorting a list of persons by age or keeping track of students' attendance. To compare two dates, we...

7 minutes read.

Java String concat() method:

Java String concat() method is used to add the given String to the end of the current String. Syntax: public String concat(String str) Parameter: Str: String to be concatenated at the end of current...

1 minute read.

Method chaining in Java

Method chaining in Java is the act of calling a series of methods one after the other. The sole distinction between it and function Object () constructor chaining is the difference...

3 minutes read.

Java.sql.Time Format

In JDBC API as a cover aroundjava.util.Date that handles SQL-specific requirements we use the java.sql.Time. The java.sql.Time extends java.util.Date class. To represent SQL TIME, without a date this class is...

6 minutes read.

Monsoon Umbrella Problem in Java

The Monsoon Umbrella problem is a classic Java programming problem used to test the skills of a programmer. The problem involves writing a program to determine the number of umbrellas...

3 minutes read.

Java Image

For all other classes used for representing graphical images, Java's Image class serves as an abstract superclass. For images in Java, a specific form of object known as a BufferedImage...

4 minutes read.

Streams in Java

The conventional Java SE 8 version came with many new peculiarities, out of which the most striking of which are assuredly lambda expressions and the method references. Streams and Streams...

14 minutes read.

3N+1 problem program in Java

The 3N+1 problem is a hypothesis in the field of abstract mathematics (not yet proven). Collectively known as the Collatz problem. This tutorial will describe about the 3N+1 problem and...

3 minutes read.

Sleep Time in Java

Sleep is amethod in java that is related to thread class and it is a concept of multithreading and is used to stop the execution of the current thread a...

4 minutes read.

Ternary Operator in Java

In some cases, the if...else expression in Java can be replaced by a ternary operator. Visit the Java if...else statement first before learning about the ternary operator. Ternary operator in Java A...

3 minutes read.

Types of Assignment Operators in Java

In this tutorial, we are going to study assignment operators and their types in Java language. Before proceeding to the types, let us know the term ‘assignment operator’.  The assignment...

5 minutes read.

Centered Square Numbers in Java

In this tutorial, we will understand how to check the number is a centered square number. It is one of the prevalent interview questions of IT companies. Firstly, we will...

3 minutes read.

Java vs Golang

Java Java is both a programming language and a platform. Java is a high-level, dependable, object-oriented, and secure programming language. Java was developed in 1995 by Sun Microsystems, which is now an...

4 minutes read.

This Operator Using in Java

this keyword in Java has a wide range of applications. this reference variable in Programming language refers to the object of interest. This keyword is used in Java. this keyword is...

5 minutes read.