Given a binary tree and the task is to find the spiral order traversal of the tree and return the list containing the elements. Spiral order Traversal: Starting from level 0 for root node, for all the even levels we print the node's value from right to left and for all the odd levels we print the node's value from left to right.
Example:
Input: root = [1, 2, 3, 7, 6, 5, 4]
Output: [1, 2, 3, 4, 5, 6, 7, 8, 9] Explanation: Start with root (1), print level 0 (right to left), level 1 (left to right), and continue alternating.
Input: root = [1, 3, 2]
Output: [1, 3, 2] Explanation: Start with root (1), print level 0 (right to left), then level 1 (left to right)
Input: root = [10, 20, 30, 40, 60]
Output: [10, 20, 30, 60, 40] Explanation: Start with root (10), print level 0 (right to left), level 1 (left to right), and continue alternating.
The idea is to first calculate the height of the tree, then recursively traverse each level and print the level order traversal according to the current level being odd or even.
Follow the below steps to Implement the idea:
1. Initialize Variables:
h: Calculate the height of the binary tree (i.e., the number of levels).
ltr: A boolean flag to control the left-to-right or right-to-left traversal. Initialize it to false.
i: Loop variable to traverse each level from 1 to h.
2. Level-wise Traversal:
Loop from 1 to h (height of the tree).
For each level:
Call a recursive function to print nodes at the current level (printGivenLevel(tree, level, ltr)).
After printing each level, toggle the ltr flag (ltr = !ltr), to alternate the direction for the next level.
3. Recursive Function (printGivenLevel(tree, level, ltr)):
Base Case: If the node is NULL, return.
If the current level == 1, print the node's data.
If the level > 1:
If ltr is true, recursively print the left subtree first, then the right subtree.
If ltr is false, recursively print the right subtree first, then the left subtree.
4. Toggle the Direction:
After each level, flip the value of ltr to change the direction of traversal for the next level.
C++
#include<iostream>#include<vector>usingnamespacestd;structNode{intdata;Node*left;Node*right;Node(intdata){this->data=data;left=right=nullptr;}};intheight(Node*node){if(node==nullptr)return0;intleftHeight=height(node->left);intrightHeight=height(node->right);returnmax(leftHeight,rightHeight)+1;}// Main recursive function that stores the// spiral traversal in vector res.voidgetLevel(Node*root,intlevel,boolltr,vector<int>&res){if(root==nullptr)return;if(level==1)res.push_back(root->data);elseif(level>1){if(ltr){getLevel(root->left,level-1,ltr,res);getLevel(root->right,level-1,ltr,res);}else{getLevel(root->right,level-1,ltr,res);getLevel(root->left,level-1,ltr,res);}}}vector<int>findSpiral(Node*root){vector<int>res;inth=height(root);boolltr=false;for(inti=1;i<=h;i++){getLevel(root,i,ltr,res);ltr=!ltr;}returnres;}intmain(){Node*root=newNode(1);root->left=newNode(2);root->right=newNode(3);root->left->left=newNode(7);root->left->right=newNode(6);root->right->left=newNode(5);root->right->right=newNode(4);vector<int>res=findSpiral(root);for(intx:res)cout<<x<<" ";return0;}
Java
importjava.util.ArrayList;// Class representing a node of the binary treeclassNode{intdata;Nodeleft,right;Node(intdata){this.data=data;left=right=null;}}classGfG{// Function to calculate the height of the binary treestaticintheight(Nodenode){if(node==null)return0;intleftHeight=height(node.left);intrightHeight=height(node.right);// Height is max of left/right subtree + 1 (for current node)returnMath.max(leftHeight,rightHeight)+1;}// Function to perform spiral (zig-zag) level order traversalstaticArrayList<Integer>findSpiral(Noderoot){ArrayList<Integer>result=newArrayList<>();inth=height(root);// Get height of treebooleanleftToRight=false;// Direction flag// Traverse each levelfor(intlevel=1;level<=h;level++){getLevel(root,level,leftToRight,result);leftToRight=!leftToRight;}returnresult;}// Helper function to get nodes at a given level in desired orderstaticvoidgetLevel(Noderoot,intlevel,booleanleftToRight,ArrayList<Integer>result){if(root==null)return;if(level==1){// If it's the current level, add node to resultresult.add(root.data);}else{// Recur for left and right children in// order based on directionif(leftToRight){getLevel(root.left,level-1,leftToRight,result);getLevel(root.right,level-1,leftToRight,result);}else{getLevel(root.right,level-1,leftToRight,result);getLevel(root.left,level-1,leftToRight,result);}}}// Main function to test the spiral traversalpublicstaticvoidmain(String[]args){// Creating a binary treeNoderoot=newNode(1);root.left=newNode(2);root.right=newNode(3);root.left.left=newNode(7);root.left.right=newNode(6);root.right.left=newNode(5);root.right.right=newNode(4);// Performing spiral traversalArrayList<Integer>res=findSpiral(root);// Printing the resultfor(intval:res)System.out.print(val+" ");}}
Python
#include <iostream>#include <vector>classNode:def__init__(self,data):self.data=dataself.left=Noneself.right=Nonedefheight(node):ifnodeisNone:return0leftHeight=height(node.left)rightHeight=height(node.right)returnmax(leftHeight,rightHeight)+1deffindSpiral(root):res=[]h=height(root)ltr=Falseforiinrange(1,h+1):getLevel(root,i,ltr,res)ltr=notltrreturnres# Main recursive function that stores the# spiral traversal in list res.defgetLevel(root,level,ltr,res):ifrootisNone:returniflevel==1:res.append(root.data)eliflevel>1:ifltr:getLevel(root.left,level-1,ltr,res)getLevel(root.right,level-1,ltr,res)else:getLevel(root.right,level-1,ltr,res)getLevel(root.left,level-1,ltr,res)if__name__=='__main__':root=Node(1)root.left=Node(2)root.right=Node(3)root.left.left=Node(7)root.left.right=Node(6)root.right.left=Node(5)root.right.right=Node(4)res=findSpiral(root)forxinres:print(x,end=' ')
Time Complexity: O(n) Auxiliary Space: O(h), for recursive stack space.
Using Two Stacks - O(n) Time and O(n) Space
The idea is to use two stacks. One stack s1 is used to traverse the current level and the other stack s2 is used to store the nodes of next level.
1. Initialize two stackss1 and s2, and push the root of the tree into s1.
2. While loop: Continue as long as either s1 or s2 contains nodes.
Traverse s1:
Pop the top node from s1, and add to the result.
If the node has a right child, push it to s2.
If the node has a left child, push it to s2.
Traverse s2:
Pop the top node from s2, and add to the result
If the node has a left child, push it to s1.
If the node has a right child, push it to s1.
3. Alternating Directions: This traversal alternates as we first push right in s2 and first push left in s1.
C++
#include<iostream>#include<vector>#include<stack>usingnamespacestd;structNode{intdata;Node*left,*right;Node(intval){data=val;left=right=nullptr;}};vector<int>findSpiral(Node*root){vector<int>res;if(root==nullptr)returnres;stack<Node*>s1;// Current levelstack<Node*>s2;// Next levels1.push(root);while(!s1.empty()||!s2.empty()){// Print nodes of current level from s1// and push nodes of next level to s2while(!s1.empty()){Node*temp=s1.top();s1.pop();res.push_back(temp->data);if(temp->right)s2.push(temp->right);if(temp->left)s2.push(temp->left);}// Print nodes of current level from s2// and push nodes of next level to s1while(!s2.empty()){Node*temp=s2.top();s2.pop();res.push_back(temp->data);if(temp->left)s1.push(temp->left);if(temp->right)s1.push(temp->right);}}returnres;}intmain(){Node*root=newNode(1);root->left=newNode(2);root->right=newNode(3);root->left->left=newNode(7);root->left->right=newNode(6);root->right->left=newNode(5);root->right->right=newNode(4);vector<int>res=findSpiral(root);for(intx:res)cout<<x<<" ";return0;}
Java
importjava.util.*;// Class representing a node in the binary treeclassNode{intdata;Nodeleft,right;Node(intval){data=val;left=right=null;}}classGfG{// Function to perform spiral (zigzag) traversal of a binary treestaticArrayList<Integer>findSpiral(Noderoot){ArrayList<Integer>res=newArrayList<>();if(root==null)returnres;Stack<Node>s1=newStack<>();Stack<Node>s2=newStack<>();// Push first level to first stack 's1's1.push(root);// Keep printing while any of the stacks has some nodeswhile(!s1.isEmpty()||!s2.isEmpty()){// Print nodes of current level from s1 and // push nodes of next level to s2while(!s1.isEmpty()){Nodetemp=s1.pop();res.add(temp.data);// Note that right child is pushed before leftif(temp.right!=null)s2.push(temp.right);if(temp.left!=null)s2.push(temp.left);}// Print nodes of current level from s2 and // push nodes of next level to s1while(!s2.isEmpty()){Nodetemp=s2.pop();res.add(temp.data);// Note that left child is pushed before rightif(temp.left!=null)s1.push(temp.left);if(temp.right!=null)s1.push(temp.right);}}returnres;}// Driver method to test the above logicpublicstaticvoidmain(String[]args){Noderoot=newNode(1);root.left=newNode(2);root.right=newNode(3);root.left.left=newNode(7);root.left.right=newNode(6);root.right.left=newNode(5);root.right.right=newNode(4);ArrayList<Integer>res=findSpiral(root);for(intx:res)System.out.print(x+" ");}}
Python
classNode:def__init__(self,val):self.data=valself.left=self.right=NonedeffindSpiral(root):res=[]ifrootisNone:returnress1=[]# Current levels2=[]# Next Level# Push first level to first stack 's1's1.append(root)# Keep printing while any of the stacks has some nodeswhiles1ors2:# Print nodes of current level from s1# and push nodes of next level to s2whiles1:temp=s1.pop()res.append(temp.data)# Note that right child is pushed before leftiftemp.right:s2.append(temp.right)iftemp.left:s2.append(temp.left)# Print nodes of current level from s2 # and push nodes of next level to s1whiles2:temp=s2.pop()res.append(temp.data)# Note that left child is pushed before rightiftemp.left:s1.append(temp.left)iftemp.right:s1.append(temp.right)returnresif__name__=='__main__':root=Node(1)root.left=Node(2)root.right=Node(3)root.left.left=Node(7)root.left.right=Node(6)root.right.left=Node(5)root.right.right=Node(4)res=findSpiral(root)print(' '.join(map(str,res)))
C#
usingSystem;usingSystem.Collections.Generic;classNode{publicintdata;publicNodeleft,right;publicNode(intval){data=val;left=right=null;}}classGfG{publicstaticList<int>findSpiral(Noderoot){List<int>res=newList<int>();if(root==null)returnres;Stack<Node>s1=newStack<Node>();// Current levelStack<Node>s2=newStack<Node>();// Next Level// Push first level to first stack 's1's1.Push(root);// Keep printing while any of the stacks has some nodeswhile(s1.Count>0||s2.Count>0){// Print nodes of current level from s1 // and push nodes of next level to s2while(s1.Count>0){Nodetemp=s1.Pop();res.Add(temp.data);// Note that right child is pushed before leftif(temp.right!=null)s2.Push(temp.right);if(temp.left!=null)s2.Push(temp.left);}// Print nodes of current level from s2 // and push nodes of next level to s1while(s2.Count>0){Nodetemp=s2.Pop();res.Add(temp.data);// Note that left child is pushed before rightif(temp.left!=null)s1.Push(temp.left);if(temp.right!=null)s1.Push(temp.right);}}returnres;}staticvoidMain(){Noderoot=newNode(1);root.left=newNode(2);root.right=newNode(3);root.left.left=newNode(7);root.left.right=newNode(6);root.right.left=newNode(5);root.right.right=newNode(4);List<int>res=findSpiral(root);Console.WriteLine(string.Join(" ",res));}}
JavaScript
classNode{constructor(val){this.data=val;this.left=this.right=null;}}functionfindSpiral(root){constres=[];if(root===null)returnres;consts1=[];consts2=[];// Push first level to first stack 's1's1.push(root);// Keep printing while any of the stacks has some nodeswhile(s1.length>0||s2.length>0){// Print nodes of current level from s1 and // push nodes of next level to s2while(s1.length>0){consttemp=s1.pop();res.push(temp.data);// Note that right child is pushed before leftif(temp.right)s2.push(temp.right);if(temp.left)s2.push(temp.left);}// Print nodes of current level from // s2 and push nodes of next level to s1while(s2.length>0){consttemp=s2.pop();res.push(temp.data);// Note that left child is pushed before rightif(temp.left)s1.push(temp.left);if(temp.right)s1.push(temp.right);}}returnres;}constroot=newNode(1);root.left=newNode(2);root.right=newNode(3);root.left.left=newNode(7);root.left.right=newNode(6);root.right.left=newNode(5);root.right.right=newNode(4);constres=findSpiral(root);console.log(res.join(' '));
Output
1 2 3 4 5 6 7
Time Complexity: O(n), where n is the number of nodes in the binary tree. Auxiliary Space: O(n), for storing the nodes in the stack.
Using Deque - O(n) Time and O(n) Space
The idea is to use Doubly Ended Queues, then push and pop the nodes from each end in alternate order.
To implement the idea:
1. Initialize a deque dq and push the root of the binary tree into it.
2. Set reverse = true.
3.While the deque is not empty, repeat the following:
Set n = dq.size().
If reverse is false, do the following:
For each node in the deque, pop from the front and print the node's value.
If the left child exists, push it to the back of the deque.
If the right child exists, push it to the back of the deque.
After processing the level, set reverse = !reverse.
If reverse is true, do the following:
For each node in the deque, pop from the back and print the node's value.
If the right child exists, push it to the front of the deque.
If the left child exists, push it to the front of the deque.
After processing the level, set reverse = !reverse.
C++
#include<iostream>#include<vector>#include<deque>usingnamespacestd;structNode{intdata;Node*left;Node*right;Node(intx){data=x;left=nullptr;right=nullptr;}};vector<int>findSpiral(Node*root){vector<int>res;if(!root)returnres;deque<Node*>dq;dq.push_back(root);boolreverse=true;while(!dq.empty()){intn=dq.size();while(n--){// Push right first if reverse is trueif(reverse){Node*curr=dq.back();dq.pop_back();res.push_back(curr->data);if(curr->right)dq.push_front(curr->right);if(curr->left)dq.push_front(curr->left);}// Else push left firstelse{Node*curr=dq.front();dq.pop_front();res.push_back(curr->data);if(curr->left)dq.push_back(curr->left);if(curr->right)dq.push_back(curr->right);}}reverse=!reverse;}returnres;}intmain(){Node*root=newNode(1);root->left=newNode(2);root->right=newNode(3);root->left->left=newNode(7);root->left->right=newNode(6);root->right->left=newNode(5);root->right->right=newNode(4);vector<int>res=findSpiral(root);for(intx:res)cout<<x<<" ";return0;}
Java
importjava.util.*;// Node class representing a node of the binary treeclassNode{intdata;Nodeleft,right;Node(intx){data=x;left=null;right=null;}}classGfG{// Function to return the spiral (zigzag) traversal of the binary treestaticArrayList<Integer>findSpiral(Noderoot){ArrayList<Integer>res=newArrayList<>();if(root==null)returnres;Deque<Node>dq=newArrayDeque<>();dq.add(root);// 'reverse' indicates direction of traversal at current levelbooleanreverse=true;// Loop until all levels are processedwhile(!dq.isEmpty()){intn=dq.size();// Process all nodes at current levelwhile(n-->0){// If reverse is true, process from right to leftif(reverse){Nodecurr=dq.removeLast();res.add(curr.data);// Add right child first, then left child // to the front of dequeif(curr.right!=null)dq.addFirst(curr.right);if(curr.left!=null)dq.addFirst(curr.left);}// Else process from left to rightelse{Nodecurr=dq.removeFirst();res.add(curr.data);// Add left child first, then right child to// the end of dequeif(curr.left!=null)dq.addLast(curr.left);if(curr.right!=null)dq.addLast(curr.right);}}// Toggle direction for next levelreverse=!reverse;}returnres;}// Driver code to test the spiral traversal functionpublicstaticvoidmain(String[]args){Noderoot=newNode(1);root.left=newNode(2);root.right=newNode(3);root.left.left=newNode(7);root.left.right=newNode(6);root.right.left=newNode(5);root.right.right=newNode(4);ArrayList<Integer>res=findSpiral(root);// Print the result of spiral traversalfor(intx:res)System.out.print(x+" ");}}
Python
fromcollectionsimportdequeclassNode:def__init__(self,x):self.data=xself.left=Noneself.right=NonedeffindSpiral(root):res=[]ifnotroot:returnresdq=deque([root])reverse=Truewhiledq:n=len(dq)for_inrange(n):# Push right first if reverse is trueifreverse:curr=dq.pop()res.append(curr.data)ifcurr.right:dq.appendleft(curr.right)ifcurr.left:dq.appendleft(curr.left)else:curr=dq.popleft()res.append(curr.data)ifcurr.left:dq.append(curr.left)ifcurr.right:dq.append(curr.right)reverse=notreversereturnresif__name__=='__main__':root=Node(1)root.left=Node(2)root.right=Node(3)root.left.left=Node(7)root.left.right=Node(6)root.right.left=Node(5)root.right.right=Node(4)res=findSpiral(root)print(' '.join(map(str,res)))
C#
usingSystem;usingSystem.Collections.Generic;classNode{publicintdata;publicNodeleft,right;publicNode(intx){data=x;left=null;right=null;}}classGfG{staticList<int>findSpiral(Noderoot){List<int>res=newList<int>();if(root==null)returnres;// We are Using LinkList on place of the DequeLinkedList<Node>dq=newLinkedList<Node>();dq.AddLast(root);boolreverse=true;while(dq.Count>0){intn=dq.Count;for(inti=0;i<n;i++){if(reverse){Nodecurr=dq.Last.Value;dq.RemoveLast();res.Add(curr.data);if(curr.right!=null)dq.AddFirst(curr.right);if(curr.left!=null)dq.AddFirst(curr.left);}else{Nodecurr=dq.First.Value;dq.RemoveFirst();res.Add(curr.data);if(curr.left!=null)dq.AddLast(curr.left);if(curr.right!=null)dq.AddLast(curr.right);}}reverse=!reverse;}returnres;}staticvoidMain(){Noderoot=newNode(1);root.left=newNode(2);root.right=newNode(3);root.left.left=newNode(7);root.left.right=newNode(6);root.right.left=newNode(5);root.right.right=newNode(4);List<int>res=findSpiral(root);foreach(intxinres)Console.Write(x+" ");}}
JavaScript
// Node class for the binary treeclassNode{constructor(x){this.data=x;this.left=null;this.right=null;}}// Node class for dequeclassDequeNode{constructor(value){this.value=value;this.prev=null;this.next=null;}}// Custom Deque class (Doubly Linked List)classDeque{constructor(){this.front=null;this.rear=null;this.length=0;}isEmpty(){returnthis.length===0;}pushFront(value){constnode=newDequeNode(value);if(this.isEmpty()){this.front=this.rear=node;}else{node.next=this.front;this.front.prev=node;this.front=node;}this.length++;}pushBack(value){constnode=newDequeNode(value);if(this.isEmpty()){this.front=this.rear=node;}else{node.prev=this.rear;this.rear.next=node;this.rear=node;}this.length++;}popFront(){if(this.isEmpty())returnnull;constnode=this.front;if(this.front===this.rear){this.front=this.rear=null;}else{this.front=this.front.next;this.front.prev=null;}this.length--;returnnode.value;}popBack(){if(this.isEmpty())returnnull;constnode=this.rear;if(this.front===this.rear){this.front=this.rear=null;}else{this.rear=this.rear.prev;this.rear.next=null;}this.length--;returnnode.value;}size(){returnthis.length;}}// Function to perform spiral (zigzag) traversal using custom dequefunctionfindSpiral(root){constres=[];if(!root)returnres;constdq=newDeque();dq.pushBack(root);letreverse=true;while(!dq.isEmpty()){letn=dq.size();while(n-->0){if(reverse){constcurr=dq.popBack();res.push(curr.data);// Right child is pushed first, then leftif(curr.right)dq.pushFront(curr.right);if(curr.left)dq.pushFront(curr.left);}else{constcurr=dq.popFront();res.push(curr.data);// Left child is pushed first, then rightif(curr.left)dq.pushBack(curr.left);if(curr.right)dq.pushBack(curr.right);}}reverse=!reverse;}returnres;}// Example usageconstroot=newNode(1);root.left=newNode(2);root.right=newNode(3);root.left.left=newNode(7);root.left.right=newNode(6);root.right.left=newNode(5);root.right.right=newNode(4);constres=findSpiral(root);console.log(res.join(' '));
Output
1 2 3 4 5 6 7
Time Complexity: O(n), where n is the number of nodes in the binary tree. Auxiliary Space: O(n), for storing the nodes in the Deque.