Iterative Boundary Traversal of Complete Binary tree
Last Updated :
15 Sep, 2022
Given a complete binary tree, traverse it such that all the boundary nodes are visited in Anti-Clockwise order starting from the root.
Example:
Input:
18
/ \
15 30
/ \ / \
40 50 100 20
Output: 18 15 40 50 100 20 30
Approach:
- Traverse left-most nodes of the tree from top to down. (Left boundary)
- Traverse bottom-most level of the tree from left to right. (Leaf nodes)
- Traverse right-most nodes of the tree from bottom to up. (Right boundary)
We can traverse the left boundary quite easily with the help of a while loop that checks when the node doesn’t have any left child. Similarly, we can traverse the right boundary quite easily with the help of a while loop that checks when the node doesn’t have any right child.
The main challenge here is to traverse the last level of the tree in left to right order. To traverse level-wise there is BFS and order of left to right can be taken care of by pushing left nodes in the queue first. So the only thing left now is to make sure it is the last level. Just check whether the node has any child and only include them.
We will have to take special care of the corner case that same nodes are not traversed again. In the example above 40 is a part of the left boundary as well as leaf nodes. Similarly, 20 is a part of the right boundary as well as leaf nodes.
So we will have to traverse only till the second last node of both the boundaries in that case. Also keep in mind we should not traverse the root again.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
struct Node {
int data;
struct Node *left, *right;
};
struct Node* newNode( int data)
{
Node* temp = new Node;
temp->data = data;
temp->left = temp->right = NULL;
return temp;
}
void boundaryTraversal(Node* root)
{
if (root) {
if (!(root->left) && !(root->right)) {
cout << root->data << endl;
return ;
}
vector<Node*> list;
list.push_back(root);
Node* L = root->left;
while (L->left) {
list.push_back(L);
L = L->left;
}
queue<Node*> q;
q.push(root);
while (!q.empty()) {
Node* temp = q.front();
q.pop();
if (!(temp->left) && !(temp->right)) {
list.push_back(temp);
}
if (temp->left) {
q.push(temp->left);
}
if (temp->right) {
q.push(temp->right);
}
}
vector<Node*> list_r;
Node* R = root->right;
while (R->right) {
list_r.push_back(R);
R = R->right;
}
reverse(list_r.begin(), list_r.end());
list.insert(list.end(), list_r.begin(),
list_r.end());
for ( auto i : list) {
cout << i->data << " " ;
}
cout << endl;
return ;
}
}
int main()
{
Node* root = newNode(20);
root->left = newNode(8);
root->right = newNode(22);
root->left->left = newNode(4);
root->left->right = newNode(12);
root->right->left = newNode(10);
root->right->right = newNode(25);
boundaryTraversal(root);
return 0;
}
|
Java
import java.util.*;
class GFG{
static class Node {
int data;
Node left, right;
};
static Node newNode( int data)
{
Node temp = new Node();
temp.data = data;
temp.left = temp.right = null ;
return temp;
}
static void boundaryTraversal(Node root)
{
if (root != null ) {
if ((root.left == null ) && (root.right == null )) {
System.out.print(root.data + "\n" );
return ;
}
Vector<Node> list = new Vector<Node>();
list.add(root);
Node L = root.left;
while (L.left != null ) {
list.add(L);
L = L.left;
}
Queue<Node> q = new LinkedList<>();
q.add(root);
while (!q.isEmpty()) {
Node temp = q.peek();
q.remove();
if ((temp.left == null ) && (temp.right == null )) {
list.add(temp);
}
if (temp.left != null ) {
q.add(temp.left);
}
if (temp.right != null ) {
q.add(temp.right);
}
}
Vector<Node> list_r = new Vector<Node>();
Node R = root.right;
while (R.right != null ) {
list_r.add(R);
R = R.right;
}
Collections.reverse(list_r);
list.addAll(list_r);
for (Node i : list) {
System.out.print(i.data + " " );
}
System.out.println();
return ;
}
}
public static void main(String[] args)
{
Node root = newNode( 20 );
root.left = newNode( 8 );
root.right = newNode( 22 );
root.left.left = newNode( 4 );
root.left.right = newNode( 12 );
root.right.left = newNode( 10 );
root.right.right = newNode( 25 );
boundaryTraversal(root);
}
}
|
Python
from collections import deque
class Node:
def __init__( self , key):
self .data = key
self .left = None
self .right = None
def boundaryTraversal(root):
if root:
if not root.left and not root.right:
print (root.data)
return
list = []
list .append(root)
temp = root.left
while temp.left:
list .append(temp)
temp = temp.left
q = deque()
q.append(root)
while len (q) ! = 0 :
x = q.pop()
if not x.left and not x.right:
list .append(x)
if x.right:
q.append(x.right)
if x.left:
q.append(x.left)
list_r = []
temp = root.right
while temp.right:
list .append(temp)
temp = temp.right
list_r = list_r[:: - 1 ]
list + = list_r
print ( " " .join([ str (i.data) for i in list ]))
return
root = Node( 20 )
root.left = Node( 8 )
root.right = Node( 22 )
root.left.left = Node( 4 )
root.left.right = Node( 12 )
root.right.left = Node( 10 )
root.right.right = Node( 25 )
boundaryTraversal(root)
|
C#
using System;
using System.Collections.Generic;
class GFG
{
class Node
{
public int data;
public Node left, right;
};
static Node newNode( int data)
{
Node temp = new Node();
temp.data = data;
temp.left = temp.right = null ;
return temp;
}
static void boundaryTraversal(Node root)
{
if (root != null )
{
if ((root.left == null ) &&
(root.right == null ))
{
Console.Write(root.data + "\n" );
return ;
}
List<Node> list = new List<Node>();
list.Add(root);
Node L = root.left;
while (L.left != null )
{
list.Add(L);
L = L.left;
}
Queue<Node> q = new Queue<Node>();
q.Enqueue(root);
while (q.Count != 0)
{
Node temp = q.Peek();
q.Dequeue();
if ((temp.left == null ) &&
(temp.right == null ))
{
list.Add(temp);
}
if (temp.left != null )
{
q.Enqueue(temp.left);
}
if (temp.right != null )
{
q.Enqueue(temp.right);
}
}
List<Node> list_r = new List<Node>();
Node R = root.right;
while (R.right != null )
{
list_r.Add(R);
R = R.right;
}
list_r.Reverse();
list.InsertRange(list.Count-1, list_r);
foreach (Node i in list)
{
Console.Write(i.data + " " );
}
Console.WriteLine();
return ;
}
}
public static void Main(String[] args)
{
Node root = newNode(20);
root.left = newNode(8);
root.right = newNode(22);
root.left.left = newNode(4);
root.left.right = newNode(12);
root.right.left = newNode(10);
root.right.right = newNode(25);
boundaryTraversal(root);
}
}
|
Javascript
<script>
class Node
{
constructor(data) {
this .left = null ;
this .right = null ;
this .data = data;
}
}
function newNode(data)
{
let temp = new Node(data);
return temp;
}
function boundaryTraversal(root)
{
if (root != null ) {
if ((root.left == null ) && (root.right == null )) {
document.write(root.data + "</br>" );
return ;
}
let list = [];
list.push(root);
let L = root.left;
while (L.left != null ) {
list.push(L);
L = L.left;
}
let q = [];
q.push(root);
while (q.length > 0) {
let temp = q[0];
q.shift();
if ((temp.left == null ) && (temp.right == null )) {
list.push(temp);
}
if (temp.left != null ) {
q.push(temp.left);
}
if (temp.right != null ) {
q.push(temp.right);
}
}
let list_r = [];
let R = root.right;
while (R.right != null ) {
list_r.push(R);
R = R.right;
}
list_r.reverse();
for (let i = 0; i < list_r.length; i++)
{
list.push(list_r[i]);
}
for (let i = 0; i < list.length; i++) {
document.write(list[i].data + " " );
}
document.write( "</br>" );
return ;
}
}
let root = newNode(20);
root.left = newNode(8);
root.right = newNode(22);
root.left.left = newNode(4);
root.left.right = newNode(12);
root.right.left = newNode(10);
root.right.right = newNode(25);
boundaryTraversal(root);
</script>
|
Output
20 8 4 12 10 25 22
Share your thoughts in the comments
Please Login to comment...