Zigzag Traversal of a Binary Tree in Java

The zigzag traversal of a binary tree means for the node at the top level we go from left to right, then for the next level, we go from right to left, and thus, we keep on changing the direction from left to right, and then from right to left. Note that at the top level, we can go from right to left, instead of left to right, then for the next level, we have to go from left to right. The important point to remember for the zigzag traversal of a binary tree in Java is that at each level, the direction of traversal is opposite of the previous level. In this tutorial, we will discuss the various approaches using which one can achieve the zigzag traversal of a binary tree. Note that each approach is very important from the interview point of view.

For the following binary tree:

Zigzag Traversal of a Binary Tree in Java

The zigzag traversal is: 18 30 20 60 34 45 65 41 71 59 31 82 98 50 12

OR

The zigzag traversal is: 18 20 30 65 45 34 60 12 50 98 82 31 59 71 41

Approach 1: Using Two Stacks

The zigzag traversal of a binary tree can be achieved using two stacks. Treat the first stack as the currentLevel stack and the second stack as the nextLevel stack. A variable is also required to get the information about the current level order (whether the traversal is right to left or left to right). We do pop nodes from the currentlevel stack and display the value of nodes. Whenever the traversal for the current level order is from left to right, then we push its left child first, then its right child to the nextlevel stack. We know that a stack works on a Last In First Out (LIFO) principle. Therefore, the next time when nodes are popped off from the nextlevel stack, the order of traversal will be reversed. Similarly, when the order of traversal is from right to left, we push the right child first, then the left child of the current node. Note that after the end of each level (end of level means each node of that level is traversed), we must interchange the stacks, i.e., the nextlevel stack becomes the currentlevel stack, and the currentlevel stack becomes the nextlevel stack.

Implementation

Let's see the implementation of the zigzag traversal of a binary tree using two stacks.

FileName: ZigZagTraversalExample.java

Output:

The zigzag traversal of the binary tree is: 
18 30 20 60 34 45 65 41 71 59 31 82 98 50 12

Time Complexity: There is only one while loop in the program. Therefore, the time complexity of the above program is O(n), where n is the total number of nodes present in the binary tree.

Space Complexity: There are two stacks present in the program; each stack takes the space complexity of O(n), where n is the total number of nodes present in the binary tree. Thus, O(n) + O(n) = O(2 * n), which in terms of asymptotic complexity is equal to O(n).

Approach 2: Using Deque

The zigzag traversal of a binary tree can also be achieved using a deque. The important point to take care of is to decide whether the pop operation is performed from the front side or from the rear side. It is the pop operation that decides whether we are traversing from left to right or from right to left.

Implementation

Let's see the implementation of the zigzag traversal of a binary tree using a deque.

FileName: ZigZagTraversalExample1.java

Output:

The zigzag traversal of the binary tree is: 
18 30 20 60 34 45 65 41 71 59 31 82 98 50 12

Time Complexity: Since we are visiting a node only once; therefore, the time complexity of the above program is O(n), where n is the total number of nodes present in the binary tree.

Space Complexity: The maximum size of the deque can go upto O((n + 1) / 2), which is equal to O(n) in terms of asymptotic complexity, where n is the total number of nodes present in the binary tree. Note that (n + 1) / 2 is the total number of leaf nodes in a full binary tree.

Approach 3: Using Recursion

Using recursion also one can achieve the zigzag traversal of the binary tree. The concept is to use the level order traversal of a binary tree in a different manner. The direction in which the traversal is going on will be determined by a variable whose value toggles between 0 and 1. Note that the value of the variable changes after the completion of the traversal of each level.

Implementation

Let's see the implementation of the zigzag traversal of a binary tree using recursion.

FileName: ZigZagTraversalExample2.java

Output:

The zigzag traversal of the binary tree is: 
18 30 20 60 34 45 65 41 71 59 31 82 98 50 12

Time Complexity: Since we are visiting a node only once; therefore, the time complexity of the above program is O(n), where n represents the total number of nodes present in the binary tree.

Space Complexity: The space complexity of the above program is O(n).

Approach 4: Using Stack and Queue

In this approach, we do a level order traversal but not in the same direction for every level. In a level, when traversing from the direction left to right, we add all the encountered nodes to the array list keep. We also store the nodes for the next level in the stack. When traversing from the direction right to left, we pop the node from the stack that was being stored in the last step. The popped node is stored in the array list keep. We eventually return the array list keep. Note that the optimization of this approach is the approach where we used deque.

Implementation

Let's see the implementation of the zigzag traversal of using stack and queue.

FileName: ZigZagTraversalExample3.java

Output:

The zigzag traversal of the binary tree is: 
18 30 20 60 34 45 65 41 71 59 31 82 98 50 12

Time Complexity: For the above program, the time complexity is O(n), where n represents the total number of nodes present in the binary tree.

Space Complexity: The space complexity of the above program is O(n).