Related Articles

# Vertical Zig-Zag traversal of a Tree

• Difficulty Level : Hard
• Last Updated : 22 Jun, 2021

Given a Binary Tree, the task is to print the elements in the Vertical Zig-Zag traversal order.
Vertical Zig-Zag traversal of a tree is defined as:

1. Print the elements of the first level in the order from right to left, if there are no elements left then skip to the next level.
2. Print the elements of the last level in the order from left to right, if there are no elements left then skip to the previous level.
3. Repeat the above steps while there are nodes left to traverse.

Examples:

```Input:
1
/     \
2       3
\     /  \
4    5    6
/          \
7            8
Output: 1, 7, 3, 8, 2, 4, 6, 5
Explanation:
1. First print elements of 1st level
which will be printed as follows: 1

2. Now remaining part of the tree is
*
/    \
2       3
\     /  \
4    5     6
/           \
7              8

3. Now move to 4th level print
from leftmost one element,
which will be: 7

4. Now tree becomes:
*
/     \
2       3
\     /  \
4    5    6
/          \
*           8

5. Now move to since we move
from 2nd level since we move
from the lower level to higher-level
so start from rightmost,
so the element will be: 3

6. Now tree becomes:
*
/     \
2       *
\     /  \
4    5    6
/          \
*            8

7. Now again move to 4th level
print from the leftmost remaining element,
which will be 8

8. Now tree becomes:
*
/     \
2       *
\     /  \
4    5    6
/          \
*            *

9. Now again move to 2nd level
print from the rightmost remaining element,
which will be 2 continue this way
until all elements are not traversed```

Approach: Create a vector tree[] where tree[i] will store all the nodes of the tree at level i. Take two pointers p1 pointing to the first level and p2 pointing to the last level. Now, start printing the nodes in an alternate fashion using these two pointers (i.e. right to left for p1 and left to right for p2). If there are no nodes left in the level pointed by p1 then move to the next level and if there are no nodes left in the level pointed by p2 then move to the previous level.

Below is the implementation of the above approach:

## C++

 `// C++ program to print Vertical``// Zig-Zag traversal of tree``#include ``using` `namespace` `std;` `const` `int` `sz = 1e5;``int` `maxLevel = 0;` `// Adjacency list representation``// of the tree``vector<``int``> tree[sz + 1];` `// Boolean array to mark all the``// vertices which are visited``bool` `vis[sz + 1];` `// Integer array to store the level``// of each node``int` `level[sz + 1];` `// Array of vector where ith index``// stores all the nodes at level i``vector<``int``> nodes[sz + 1];` `// Utility function to create an``// edge between two vertices``void` `addEdge(``int` `a, ``int` `b)``{` `    ``// Add a to b's list``    ``tree[a].push_back(b);` `    ``// Add b to a's list``    ``tree[b].push_back(a);``}` `// Modified Breadth-First Function``void` `bfs(``int` `node)``{` `    ``// Create a queue of {child, parent}``    ``queue > qu;` `    ``// Push root node in the front of``    ``// the queue and mark as visited``    ``qu.push({ node, 0 });``    ``nodes.push_back(node);``    ``vis[node] = ``true``;``    ``level = 0;` `    ``while` `(!qu.empty()) {` `        ``pair<``int``, ``int``> p = qu.front();` `        ``// Dequeue a vertex from queue``        ``qu.pop();``        ``vis[p.first] = ``true``;` `        ``// Get all adjacent vertices of the dequeued``        ``// vertex s. If any adjacent has not``        ``// been visited then enqueue it``        ``for` `(``int` `child : tree[p.first]) {` `            ``if` `(!vis[child]) {` `                ``qu.push({ child, p.first });``                ``level[child] = level[p.first] + 1;``                ``maxLevel = max(maxLevel, level[child]);``                ``nodes[level[child]].push_back(child);``            ``}``        ``}``    ``}``}` `// Utility Function to display the pattern``void` `display()``{``    ``bool` `flag = ``true``;` `    ``// Pointers for the first and the last levels``    ``int` `p1 = 0, p2 = maxLevel;` `    ``// i points to the last node of level``    ``// p1 and j points to the first``    ``// node of the level p2``    ``int` `i = nodes[p1].size() - 1, j = 0;` `    ``// While there are nodes left to traverse``    ``while` `(p1 <= p2) {` `        ``// Print the nodes in an alternate fashion``        ``if` `(flag) {` `            ``// Print the last unvisited node``            ``// of the level p1``            ``cout << nodes[p1][i] << ``" "``;` `            ``// Move to the previous node``            ``i--;` `            ``// If there are no nodes left then``            ``// move to the next level``            ``if` `(i < 0) {``                ``p1++;``                ``i = nodes[p1].size() - 1;``            ``}``        ``}``        ``else` `{` `            ``// Print the first unvisited node``            ``// of the level p2``            ``cout << nodes[p2][j] << ``" "``;` `            ``// Move to the next node``            ``j++;` `            ``// If there are no nodes left then``            ``// move to the previous level``            ``if` `(j >= nodes[p2].size()) {``                ``p2--;``                ``j = 0;``            ``}``        ``}` `        ``// Change the flag``        ``flag = !flag;` `        ``// If all the nodes have been traversed``        ``if` `(p1 >= p2 && i < j) {``            ``break``;``        ``}``    ``}``}` `// Driver code``int` `main()``{` `    ``// Number of vertices``    ``int` `n = 8;` `    ``addEdge(1, 2);``    ``addEdge(1, 3);``    ``addEdge(2, 4);``    ``addEdge(3, 5);``    ``addEdge(3, 6);``    ``addEdge(4, 7);``    ``addEdge(6, 8);` `    ``// Calling modified bfs function``    ``bfs(1);` `    ``display();` `    ``return` `0;``}`

## Java

 `// Java program to print vertical``// Zig-Zag traversal of tree``import` `java.util.*;` `@SuppressWarnings``(``"unchecked"``)``class` `GFG{`` ` `static` `int` `sz = ``100000``;``static` `int` `maxLevel = ``0``;``  ` `// Adjacency list``// representation of the tree``static` `ArrayList []tree = ``new` `ArrayList[sz + ``1``];``  ` `// Boolean array to mark all the``// vertices which are visited``static` `boolean` `[]vis = ``new` `boolean``[sz + ``1``];``  ` `// Integer array to store``// the level of each node``static` `int` `[]level = ``new` `int``[sz + ``1``];``  ` `// Array of vector where ith index``// stores all the nodes at level i``static` `ArrayList []nodes = ``new` `ArrayList[sz + ``1``];``  ` `// Utility function to create an``// edge between two vertices``static` `void` `addEdge(``int` `a, ``int` `b)``{``    ` `    ``// Add a to b's list``    ``tree[a].add(b);``  ` `    ``// Add b to a's list``    ``tree[b].add(a);``}` `static` `class` `Pair``{``    ``int` `Key, Value;``    ` `    ``Pair(``int` `Key, ``int` `Value)``    ``{``        ``this``.Key = Key;``        ``this``.Value = Value;``    ``}``}``  ` `// Modified Breadth-First Function``static` `void` `bfs(``int` `node)``{``    ` `    ``// Create a queue of {child, parent}``    ``Queue qu = ``new` `LinkedList<>();``    ` `    ``// Push root node in the front of``    ``// the queue and mark as visited``    ``qu.add(``new` `Pair(node, ``0``));``    ``nodes[``0``].add(node);``    ``vis[node] = ``true``;``    ``level[``1``] = ``0``;``     ` `    ``while` `(qu.size() != ``0``)``    ``{``        ``Pair p = qu.poll();``        ` `        ``vis[p.Key] = ``true``;``         ` `        ``// Get all adjacent vertices of the``        ``// dequeued vertex s. If any adjacent``        ``// has not been visited then enqueue it``        ``for``(``int` `child : (ArrayList)tree[p.Key])``        ``{``            ``if` `(!vis[child])``            ``{``                ``qu.add(``new` `Pair(child, p.Key));``                ``level[child] = level[p.Key] + ``1``;``                ``maxLevel = Math.max(maxLevel,``                                    ``level[child]);``                ``nodes[level[child]].add(child);``            ``}``        ``}``    ``}``}``  ` `// Function to display``// the pattern``static` `void` `display()``{``    ``boolean` `flag = ``true``;``   ` `    ``// Pointers for the first and``    ``// the last levels``    ``int` `p1 = ``0``, p2 = maxLevel;``  ` `    ``// i points to the last node of level``    ``// p1 and j points to the first``    ``// node of the level p2``    ``int` `i = nodes[p1].size() - ``1``, j = ``0``;``  ` `    ``// While there are nodes left``    ``// to traverse``    ``while` `(p1 <= p2)``    ``{``        ` `        ``// Print the nodes in an``        ``// alternate fashion``        ``if` `(flag)``        ``{``            ` `            ``// Print the last unvisited node``            ``// of the level p1``            ``System.out.print((``int``)nodes[p1].get(i) + ``" "``);``            ` `            ``// Move to the previous node``            ``i--;``            ` `            ``// If there are no nodes left then``            ``// move to the next level``            ``if` `(i < ``0``)``            ``{``                ``p1++;``                ``i = nodes[p1].size() - ``1``;``            ``}``        ``}``        ``else``        ``{``            ` `            ``// Print the first unvisited node``            ``// of the level p2``            ``System.out.print((nodes[p2]).get(j) + ``" "``);``            ` `            ``// Move to the next node``            ``j++;``            ` `            ``// If there are no nodes left then``            ``// move to the previous level``            ``if` `(j >= nodes[p2].size())``            ``{``                ``p2--;``                ``j = ``0``;``            ``}``        ``}``  ` `        ``// Change the flag``        ``flag = !flag;``  ` `        ``// If all the nodes have been traversed``        ``if` `(p1 >= p2 && i < j)``        ``{``            ``break``;``        ``}``    ``}``}`` ` `// Driver code``public` `static` `void` `main(String[] args)``{``    ``for``(``int` `i = ``0``; i < sz + ``1``; i++)``    ``{``        ``tree[i] = ``new` `ArrayList();``        ``nodes[i] = ``new` `ArrayList();``        ``vis[i] = ``false``;``        ``level[i] = ``0``;``    ``}`` ` `    ``addEdge(``1``, ``2``);``    ``addEdge(``1``, ``3``);``    ``addEdge(``2``, ``4``);``    ``addEdge(``3``, ``5``);``    ``addEdge(``3``, ``6``);``    ``addEdge(``4``, ``7``);``    ``addEdge(``6``, ``8``);``    ` `    ``// Calling modified bfs function``    ``bfs(``1``);``    ` `    ``display();``}``}` `// This code is contributed by pratham76`

## Python3

 `# Python3 program to print Vertical``# Zig-Zag traversal of tree``from` `collections ``import` `deque` `sz ``=` `int``(``1e5``)``maxLevel ``=` `0` `# Adjacency list representation``# of the tree``tree ``=` `[[] ``for` `_ ``in` `range``(sz ``+` `1``)]` `# Boolean array to mark all the``# vertices which are visited``vis ``=` `[``False` `for` `_ ``in` `range``(sz ``+` `1``)]` `# Integer array to store the level``# of each node``level ``=` `[``0` `for` `_ ``in` `range``(sz ``+` `1``)]` `# Array of vector where ith index``# stores all the nodes at level i``nodes ``=` `[[] ``for` `_ ``in` `range``(sz ``+` `1``)]` `# Utility function to create an``# edge between two vertices``def` `addEdge(a, b):` `    ``# Add a to b's list``    ``tree[a].append(b)` `    ``# Add b to a's list``    ``tree[b].append(a)` `# Modified Breadth-First Function``def` `bfs(node):` `    ``global` `maxLevel` `    ``# Create a queue of child, parent``    ``qu ``=` `deque()` `    ``# Push root node in the front of``    ``# the queue and mark as visited``    ``qu.append([node, ``0``])``    ``nodes[``0``].append(node)``    ``vis[node] ``=` `True``    ``level[``1``] ``=` `0` `    ``while` `qu:``        ``p ``=` `qu[``0``]` `        ``# Dequeue a vertex from queue``        ``qu.popleft()``        ``vis[p[``0``]] ``=` `True` `        ``# Get all adjacent vertices of the dequeued``        ``# vertex s. If any adjacent has not``        ``# been visited then enqueue it``        ``for` `child ``in` `tree[p[``0``]]:``            ``if` `(``not` `vis[child]):``                ``qu.append([child, p[``0``]])``                ``level[child] ``=` `level[p[``0``]] ``+` `1``                ``maxLevel ``=` `max``(maxLevel, level[child])``                ``nodes[level[child]].append(child)` `# Utility Function to display the pattern``def` `display():``    ` `    ``global` `maxLevel` `    ``flag ``=` `True` `    ``# Pointers for the first``    ``# and the last levels``    ``p1 ``=` `0``    ``p2 ``=` `maxLevel` `    ``# i points to the last node of level``    ``# p1 and j points to the first``    ``# node of the level p2``    ``i ``=` `len``(nodes[p1]) ``-` `1``    ``j ``=` `0` `    ``# While there are nodes left to traverse``    ``while` `(p1 <``=` `p2):` `        ``# Print the nodes in an alternate fashion``        ``if` `(flag):` `            ``# Print the last unvisited node``            ``# of the level p1``            ``print``(nodes[p1][i], end ``=` `" "``)` `            ``# Move to the previous node``            ``i ``-``=` `1` `            ``# If there are no nodes left then``            ``# move to the next level``            ``if` `(i < ``0``):``                ``p1 ``+``=` `1``                ``i ``=` `len``(nodes[p1]) ``-` `1``        ``else``:` `            ``# Print the first unvisited node``            ``# of the level p2``            ``print``(nodes[p2][j], end ``=` `" "``)` `            ``# Move to the next node``            ``j ``+``=` `1` `            ``# If there are no nodes left then``            ``# move to the previous level``            ``if` `(j >``=` `len``(nodes[p2])):``                ``p2 ``-``=` `1``                ``j ``=` `0` `        ``# Change the flag``        ``flag ``=` `not` `flag` `        ``# If all the nodes have been traversed``        ``if` `(p1 >``=` `p2 ``and` `i < j):``            ``break` `# Driver code``if` `__name__ ``=``=` `"__main__"``:` `    ``# Number of vertices``    ``n ``=` `8` `    ``addEdge(``1``, ``2``)``    ``addEdge(``1``, ``3``)``    ``addEdge(``2``, ``4``)``    ``addEdge(``3``, ``5``)``    ``addEdge(``3``, ``6``)``    ``addEdge(``4``, ``7``)``    ``addEdge(``6``, ``8``)` `    ``# Calling modified bfs function``    ``bfs(``1``)` `    ``display()` `# This code is contributed by sanjeev2552`

## C#

 `// C# program to print vertical``// Zig-Zag traversal of tree``using` `System;``using` `System.Collections.Generic;``using` `System.Collections;` `class` `GFG{` `static` `int` `sz = 100000;``static` `int` `maxLevel = 0;`` ` `// Adjacency list``// representation of the tree``static` `ArrayList []tree = ``new` `ArrayList[sz + 1];`` ` `// Boolean array to mark all the``// vertices which are visited``static` `bool` `[]vis = ``new` `bool``[sz + 1];`` ` `// Integer array to store``// the level of each node``static` `int` `[]level = ``new` `int``[sz + 1];`` ` `// Array of vector where ith index``// stores all the nodes at level i``static` `ArrayList []nodes = ``new` `ArrayList[sz + 1];`` ` `// Utility function to create an``// edge between two vertices``static` `void` `addEdge(``int` `a, ``int` `b)``{``    ` `    ``// Add a to b's list``    ``tree[a].Add(b);`` ` `    ``// Add b to a's list``    ``tree[b].Add(a);``}`` ` `// Modified Breadth-First Function``static` `void` `bfs(``int` `node)``{``    ` `    ``// Create a queue of {child, parent}``    ``Queue qu = ``new` `Queue();``    ` `    ``// Push root node in the front of``    ``// the queue and mark as visited``    ``qu.Enqueue(``new` `KeyValuePair<``int``, ``int``>(node, 0));``    ``nodes.Add(node);``    ``vis[node] = ``true``;``    ``level = 0;``    ` `    ``while``(qu.Count != 0)``    ``{``        ``KeyValuePair<``int``,``                     ``int``> p = (KeyValuePair<``int``,``                                            ``int``>)qu.Peek();``                                            ` `        ``// Dequeue a vertex from queue``        ``qu.Dequeue();``        ``vis[p.Key] = ``true``;``        ` `        ``// Get all adjacent vertices of the dequeued``        ``// vertex s. If any adjacent has not``        ``// been visited then enqueue it``        ``foreach``(``int` `child ``in` `tree[p.Key])``        ``{``            ``if` `(!vis[child])``            ``{``                ``qu.Enqueue(``new` `KeyValuePair<``int``, ``int``>(``                           ``child, p.Key));``                ``level[child] = level[p.Key] + 1;``                ``maxLevel = Math.Max(maxLevel,``                                    ``level[child]);``                ``nodes[level[child]].Add(child);``            ``}``        ``}``    ``}``}`` ` `// Function to display``// the pattern``static` `void` `display()``{``   ``bool` `flag = ``true``;`` ` `    ``// Pointers for the first and``    ``// the last levels``    ``int` `p1 = 0, p2 = maxLevel;`` ` `    ``// i points to the last node of level``    ``// p1 and j points to the first``    ``// node of the level p2``    ``int` `i = nodes[p1].Count - 1, j = 0;`` ` `    ``// While there are nodes left``    ``// to traverse``    ``while` `(p1 <= p2)``    ``{``        ` `        ``// Print the nodes in an``        ``// alternate fashion``        ``if` `(flag)``        ``{``            ` `            ``// Print the last unvisited node``            ``// of the level p1``            ``Console.Write((``int``)nodes[p1][i] + ``" "``);`` ` `            ``// Move to the previous node``            ``i--;`` ` `            ``// If there are no nodes left then``            ``// move to the next level``            ``if` `(i < 0)``            ``{``                ``p1++;``                ``i = nodes[p1].Count - 1;``            ``}``        ``}``        ``else``        ``{`` ` `            ``// Print the first unvisited node``            ``// of the level p2``            ``Console.Write((``int``)nodes[p2][j] + ``" "``);`` ` `            ``// Move to the next node``            ``j++;`` ` `            ``// If there are no nodes left then``            ``// move to the previous level``            ``if` `(j >= nodes[p2].Count)``            ``{``                ``p2--;``                ``j = 0;``            ``}``        ``}`` ` `        ``// Change the flag``        ``flag = !flag;`` ` `        ``// If all the nodes have been traversed``        ``if` `(p1 >= p2 && i < j)``        ``{``            ``break``;``        ``}``    ``}``}` `// Driver code``public` `static` `void` `Main(``string``[] args)``{``    ``for``(``int` `i = 0; i < sz + 1; i++)``    ``{``        ``tree[i] = ``new` `ArrayList();``        ``nodes[i] = ``new` `ArrayList();``        ``vis[i] = ``false``;``        ``level[i] = 0;``    ``}` `    ``addEdge(1, 2);``    ``addEdge(1, 3);``    ``addEdge(2, 4);``    ``addEdge(3, 5);``    ``addEdge(3, 6);``    ``addEdge(4, 7);``    ``addEdge(6, 8);``    ` `    ``// Calling modified bfs function``    ``bfs(1);``    ` `    ``display();``}``}` `// This code is contributed by rutvik_56`

## Javascript

 ``
Output:

`1 7 3 8 2 4 6 5`

Time Complexity: O(n)

Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the DSA Self Paced Course at a student-friendly price and become industry ready.  To complete your preparation from learning a language to DS Algo and many more,  please refer Complete Interview Preparation Course.

In case you wish to attend live classes with experts, please refer DSA Live Classes for Working Professionals and Competitive Programming Live for Students.

My Personal Notes arrow_drop_up