Boundary Traversal of binary tree (original) (raw)
Last Updated : 7 Oct, 2025
Given the **root of a binary tree, Find its **boundary traversal in anti-clockwise order, starting from the root.
The boundary of a binary tree consists of the following parts:
- **Left Boundary: The nodes on the left edge of the tree, excluding the leaf nodes.
- **Leaf Nodes: All the leaf nodes from left to right.
- **Right Boundary: The nodes on the right edge of the tree, excluding the leaf nodes, traversed in bottom-up order.
**Note:
- If the root does not have a left subtree or right subtree, then the root itself is considered part of the respective boundary.
- Each node in the boundary should appear only once in the traversal.
**Input :
**Output : [1, 2, 4, 8, 9, 6, 7, 3]
**Explanation:
**Input :
**Output : [1, 4, 3, 2]
**Explanation:
Table of Content
- [Approach - 1] Using Recursion - O(n) Time and O(h) Space
- [Approach - 2] Using Iteration and Morris Traversal - O(n) Time and O(h) Space
[Approach - 1] Using Recursion - O(n) Time and O(h) Space
The boundary traversal of a binary tree is done in three steps. First, we traverse the left boundary, starting from the root’s left child and moving downward, excluding any leaf nodes. Next, we collect all the leaf nodes of the tree from left to right using recursion. Finally, we traverse the right boundary, starting from the root’s right child and moving downward, again excluding leaf nodes, but the collected nodes are added in reverse order. By combining the left boundary, leaf nodes, and right boundary, we obtain the complete anti-clockwise boundary traversal of the tree.
C++ `
#include #include using namespace std;
// Node Structure class Node { public: int data; Node *left; Node *right;
Node(int x) {
data = x;
left = right = nullptr;
}};
bool isLeaf(Node *node) { return node->left == nullptr && node->right == nullptr; }
// Function to collect left boundary nodes // (top-down order) void collectLeft(Node* root, vector& res) {
// exclude leaf node
if (root == nullptr || isLeaf(root))
return;
res.push_back(root->data);
if (root->left)
collectLeft(root->left, res);
else if (root->right)
collectLeft(root->right, res);}
// Function to collect all leaf nodes void collectLeaves(Node *root, vector &res) { if (root == nullptr) return;
// Add leaf nodes
if (isLeaf(root)) {
res.push_back(root->data);
return;
}
collectLeaves(root->left, res);
collectLeaves(root->right, res);}
// Function to collect right boundary nodes // (bottom-up order) void collectRight(Node* root, vector& res) {
// exclude leaf nodes
if (root == nullptr || isLeaf(root))
return;
if (root->right)
collectRight(root->right, res);
else if (root->left)
collectRight(root->left, res);
res.push_back(root->data); }
// Function to find Boundary Traversal of Binary Tree vector boundaryTraversal(Node *root) { vector res;
if (!root)
return res;
// Add root data if it's not a leaf
if (!isLeaf(root))
res.push_back(root->data);
// Collect left boundary
collectLeft(root->left, res);
// Collect leaf nodes
collectLeaves(root, res);
// Collect right boundary
collectRight(root->right, res);
return res;}
int main() {
// Input Binary tree
// 1
// / \
// 2 3
// / \ / \
// 4 5 6 7
// / \
// 8 9
Node *root = new Node(1);
root->left = new Node(2);
root->right = new Node(3);
root->left->left = new Node(4);
root->left->right = new Node(5);
root->right->left = new Node(6);
root->right->right = new Node(7);
root->left->right->left = new Node(8);
root->left->right->right = new Node(9);
vector<int> boundary = boundaryTraversal(root);
for (int x : boundary)
cout << x << " ";
return 0;}
Java
import java.util.ArrayList; import java.util.List;
// Node Structure class Node { int data; Node left, right;
Node(int x) {
data = x;
left = right = null;
}}
class GFG {
static boolean isLeaf(Node node) {
return node.left == null && node.right == null;
}
// Function to collect left boundary nodes
// (top-down order)
static void collectLeft(Node root, ArrayList<Integer> res) {
// exclude leaf node
if (root == null || isLeaf(root))
return;
res.add(root.data);
if (root.left != null)
collectLeft(root.left, res);
else if (root.right != null)
collectLeft(root.right, res);
}
// Function to collect all leaf nodes
static void collectLeaves(Node root, ArrayList<Integer> res) {
if (root == null)
return;
// Add leaf nodes
if (isLeaf(root)) {
res.add(root.data);
return;
}
collectLeaves(root.left, res);
collectLeaves(root.right, res);
}
// Function to collect right boundary nodes
// (bottom-up order)
static void collectRight(Node root, ArrayList<Integer> res) {
// exclude leaf nodes
if (root == null || isLeaf(root))
return;
if (root.right != null)
collectRight(root.right, res);
else if (root.left != null)
collectRight(root.left, res);
res.add(root.data);
}
// Function to find Boundary Traversal of Binary Tree
static ArrayList<Integer> boundaryTraversal(Node root) {
ArrayList<Integer> res = new ArrayList<>();
if (root == null)
return res;
// Add root data if it's not a leaf
if (!isLeaf(root))
res.add(root.data);
// Collect left boundary
collectLeft(root.left, res);
// Collect leaf nodes
collectLeaves(root, res);
// Collect right boundary
collectRight(root.right, res);
return res;
}
public static void main(String[] args) {
// Input Binary tree
// 1
// / \
// 2 3
// / \ / \
// 4 5 6 7
// / \
// 8 9
Node root = new Node(1);
root.left = new Node(2);
root.right = new Node(3);
root.left.left = new Node(4);
root.left.right = new Node(5);
root.right.left = new Node(6);
root.right.right = new Node(7);
root.left.right.left = new Node(8);
root.left.right.right = new Node(9);
List<Integer> boundary = boundaryTraversal(root);
for (int x : boundary)
System.out.print(x + " ");
}}
Python
Node Structure
class Node: def init(self, x): self.data = x self.left = None self.right = None
def isLeaf(node): return node.left is None and node.right is None
Function to collect left boundary nodes
(top-down order)
def collectLeft(root, res):
# exclude leaf node
if root is None or isLeaf(root):
return
res.append(root.data)
if root.left:
collectLeft(root.left, res)
elif root.right:
collectLeft(root.right, res)Function to collect all leaf nodes
def collectLeaves(root, res): if root is None: return
# Add leaf nodes
if isLeaf(root):
res.append(root.data)
return
collectLeaves(root.left, res)
collectLeaves(root.right, res)Function to collect right boundary nodes
(bottom-up order)
def collectRight(root, res):
# exclude leaf nodes
if root is None or isLeaf(root):
return
if root.right:
collectRight(root.right, res)
elif root.left:
collectRight(root.left, res)
res.append(root.data)Function to find Boundary Traversal of Binary Tree
def boundaryTraversal(root): res = []
if not root:
return res
# Add root data if it's not a leaf
if not isLeaf(root):
res.append(root.data)
# Collect left boundary
collectLeft(root.left, res)
# Collect leaf nodes
collectLeaves(root, res)
# Collect right boundary
collectRight(root.right, res)
return resif name == "main":
# Input Binary tree
# 1
# / \
# 2 3
# / \ / \
# 4 5 6 7
# / \
# 8 9
root = Node(1)
root.left = Node(2)
root.right = Node(3)
root.left.left = Node(4)
root.left.right = Node(5)
root.right.left = Node(6)
root.right.right = Node(7)
root.left.right.left = Node(8)
root.left.right.right = Node(9)
boundary = boundaryTraversal(root)
for x in boundary:
print(x, end=" ")C#
using System; using System.Collections.Generic;
// Node Structure class Node { public int data; public Node left; public Node right;
public Node(int x) {
data = x;
left = right = null;
}}
class GFG {
static bool isLeaf(Node node) {
return node.left == null && node.right == null;
}
// Function to collect left boundary nodes
// (top-down order)
static void collectLeft(Node root, List<int> res) {
// exclude leaf node
if (root == null || isLeaf(root))
return;
res.Add(root.data);
if (root.left != null)
collectLeft(root.left, res);
else if (root.right != null)
collectLeft(root.right, res);
}
// Function to collect all leaf nodes
static void collectLeaves(Node root, List<int> res) {
if (root == null)
return;
// Add leaf nodes
if (isLeaf(root)) {
res.Add(root.data);
return;
}
collectLeaves(root.left, res);
collectLeaves(root.right, res);
}
// Function to collect right boundary nodes
// (bottom-up order)
static void collectRight(Node root, List<int> res) {
// exclude leaf nodes
if (root == null || isLeaf(root))
return;
if (root.right != null)
collectRight(root.right, res);
else if (root.left != null)
collectRight(root.left, res);
res.Add(root.data);
}
// Function to find Boundary Traversal of Binary Tree
static List<int> boundaryTraversal(Node root) {
List<int> res = new List<int>();
if (root == null)
return res;
// Add root data if it's not a leaf
if (!isLeaf(root))
res.Add(root.data);
// Collect left boundary
collectLeft(root.left, res);
// Collect leaf nodes
collectLeaves(root, res);
// Collect right boundary
collectRight(root.right, res);
return res;
}
static void Main(string[] args)
{
// Input Binary tree
// 1
// / \
// 2 3
// / \ / \
// 4 5 6 7
// / \
// 8 9
Node root = new Node(1);
root.left = new Node(2);
root.right = new Node(3);
root.left.left = new Node(4);
root.left.right = new Node(5);
root.right.left = new Node(6);
root.right.right = new Node(7);
root.left.right.left = new Node(8);
root.left.right.right = new Node(9);
List<int> boundary = boundaryTraversal(root);
foreach (int x in boundary)
Console.Write(x + " ");
}}
JavaScript
// Node Structure class Node { constructor(x) { this.data = x; this.left = null; this.right = null; } }
function isLeaf(node) { return node.left === null && node.right === null; }
// Function to collect left boundary nodes // (top-down order) function collectLeft(root, res) {
// exclude leaf node
if (root === null || isLeaf(root))
return;
res.push(root.data);
if (root.left !== null)
collectLeft(root.left, res);
else if (root.right !== null)
collectLeft(root.right, res);}
// Function to collect all leaf nodes function collectLeaves(root, res) { if (root === null) return;
// Add leaf nodes
if (isLeaf(root)) {
res.push(root.data);
return;
}
collectLeaves(root.left, res);
collectLeaves(root.right, res);}
// Function to collect right boundary nodes // (bottom-up order) function collectRight(root, res) {
// exclude leaf nodes
if (root === null || isLeaf(root))
return;
if (root.right !== null)
collectRight(root.right, res);
else if (root.left !== null)
collectRight(root.left, res);
res.push(root.data);}
// Function to find Boundary Traversal of Binary Tree function boundaryTraversal(root) { let res = [];
if (root === null)
return res;
// Add root data if it's not a leaf
if (!isLeaf(root))
res.push(root.data);
// Collect left boundary
collectLeft(root.left, res);
// Collect leaf nodes
collectLeaves(root, res);
// Collect right boundary
collectRight(root.right, res);
return res;}
// Driver Code
// Input Binary tree
// 1
// /
// 2 3
// / \ /
// 4 5 6 7
// /
// 8 9
let root = new Node(1); root.left = new Node(2); root.right = new Node(3);
root.left.left = new Node(4); root.left.right = new Node(5);
root.right.left = new Node(6); root.right.right = new Node(7);
root.left.right.left = new Node(8); root.left.right.right = new Node(9);
let boundary = boundaryTraversal(root); console.log(boundary.join(" "));
`
[Approach - 2] Using Iteration and Morris Traversal - O(n) Time and O(h) Space
The idea is to reduce the auxiliary space used by the memory stack in the above approach. This approach is similar to the previous one, but instead of recursion, we use iteration to find the left and right boundaries, and use Morris Traversal to find the leaf nodes.
C++ `
#include #include using namespace std;
// Node Structure class Node { public: int data; Node *left; Node *right;
Node(int x) {
data = x;
left = right = nullptr;
}};
bool isLeaf(Node *node) { return node->left == nullptr && node->right == nullptr; }
// Function to collect the left boundary nodes void collectLeft(Node *root, vector &res) { if (root == nullptr) return;
Node *curr = root;
while (!isLeaf(curr)) {
res.push_back(curr->data);
if (curr->left)
curr = curr->left;
else
curr = curr->right;
}}
// Function to collect the leaf nodes using Morris Traversal void collectLeaves(Node* root, vector& res) { Node* current = root;
while (current) {
if (current->left == nullptr) {
// If it's a leaf node
if (current->right == nullptr)
res.push_back(current->data);
current = current->right;
}
else {
// Find the inorder predecessor
Node* predecessor = current->left;
while (predecessor->right && predecessor->right != current) {
predecessor = predecessor->right;
}
if (predecessor->right == nullptr) {
predecessor->right = current;
current = current->left;
}
else {
// If it's predecessor is a leaf node
if (predecessor->left == nullptr)
res.push_back(predecessor->data);
predecessor->right = nullptr;
current = current->right;
}
}
}}
// Function to collect the right boundary nodes void collectRight(Node *root, vector &res) { if (root == nullptr) return;
Node *curr = root;
vector<int> temp;
while (!isLeaf(curr)) {
temp.push_back(curr->data);
if (curr->right)
curr = curr->right;
else
curr = curr->left;
}
for (int i = temp.size() - 1; i >= 0; --i)
res.push_back(temp[i]);}
// Function to perform boundary traversal vector boundaryTraversal(Node *root) { vector res;
if (!root)
return res;
// Add root data if it's not a leaf
if (!isLeaf(root))
res.push_back(root->data);
// Collect left boundary
collectLeft(root->left, res);
// Collect leaf nodes
collectLeaves(root, res);
// Collect right boundary
collectRight(root->right, res);
return res;}
int main() {
// Hardcoded Binary tree
// 1
// / \
// 2 3
// / \ / \
// 4 5 6 7
// / \
// 8 9
Node *root = new Node(1);
root->left = new Node(2);
root->right = new Node(3);
root->left->left = new Node(4);
root->left->right = new Node(5);
root->right->left = new Node(6);
root->right->right = new Node(7);
root->left->right->left = new Node(8);
root->left->right->right = new Node(9);
vector<int> boundary = boundaryTraversal(root);
for (int x : boundary)
cout << x << " ";
return 0;}
Java
import java.util.ArrayList; import java.util.List;
// Node Structure class Node { int data; Node left, right;
Node(int x) {
data = x;
left = right = null;
}}
class GFG {
static boolean isLeaf(Node node) {
return node.left == null && node.right == null;
}
// Function to collect the left boundary nodes
static void collectLeft(Node root, ArrayList<Integer> res) {
if (root == null)
return;
Node curr = root;
while (!isLeaf(curr)) {
res.add(curr.data);
if (curr.left != null)
curr = curr.left;
else
curr = curr.right;
}
}
// Function to collect the leaf nodes using Morris Traversal
static void collectLeaves(Node root, ArrayList<Integer> res) {
Node current = root;
while (current != null) {
if (current.left == null) {
// If it's a leaf node
if (current.right == null)
res.add(current.data);
current = current.right;
} else {
// Find the inorder predecessor
Node predecessor = current.left;
while (predecessor.right != null && predecessor.right != current) {
predecessor = predecessor.right;
}
if (predecessor.right == null) {
predecessor.right = current;
current = current.left;
} else {
// If its predecessor is a leaf node
if (predecessor.left == null)
res.add(predecessor.data);
predecessor.right = null;
current = current.right;
}
}
}
}
// Function to collect the right boundary nodes
static void collectRight(Node root, ArrayList<Integer> res) {
if (root == null)
return;
Node curr = root;
ArrayList<Integer> temp = new ArrayList<>();
while (!isLeaf(curr)) {
temp.add(curr.data);
if (curr.right != null)
curr = curr.right;
else
curr = curr.left;
}
for (int i = temp.size() - 1; i >= 0; --i)
res.add(temp.get(i));
}
// Function to perform boundary traversal
static ArrayList<Integer> boundaryTraversal(Node root) {
ArrayList<Integer> res = new ArrayList<>();
if (root == null)
return res;
// Add root data if it's not a leaf
if (!isLeaf(root))
res.add(root.data);
// Collect left boundary
collectLeft(root.left, res);
// Collect leaf nodes
collectLeaves(root, res);
// Collect right boundary
collectRight(root.right, res);
return res;
}
public static void main(String[] args) {
// Hardcoded Binary tree
// 1
// / \
// 2 3
// / \ / \
// 4 5 6 7
// / \
// 8 9
Node root = new Node(1);
root.left = new Node(2);
root.right = new Node(3);
root.left.left = new Node(4);
root.left.right = new Node(5);
root.right.left = new Node(6);
root.right.right = new Node(7);
root.left.right.left = new Node(8);
root.left.right.right = new Node(9);
ArrayList<Integer> boundary = boundaryTraversal(root);
for (int x : boundary)
System.out.print(x + " ");
}}
Python
Node Structure
class Node: def init(self, x): self.data = x self.left = None self.right = None
def isLeaf(node): return node.left is None and node.right is None
Function to collect the left boundary nodes
def collectLeft(root, res): if root is None: return
curr = root
while not isLeaf(curr):
res.append(curr.data)
if curr.left is not None:
curr = curr.left
else:
curr = curr.rightFunction to collect the leaf nodes using Morris Traversal
def collectLeaves(root, res): current = root
while current:
if current.left is None:
# If it's a leaf node
if current.right is None:
res.append(current.data)
current = current.right
else:
# Find the inorder predecessor
predecessor = current.left
while predecessor.right and predecessor.right != current:
predecessor = predecessor.right
if predecessor.right is None:
predecessor.right = current
current = current.left
else:
# If its predecessor is a leaf node
if predecessor.left is None:
res.append(predecessor.data)
predecessor.right = None
current = current.rightFunction to collect the right boundary nodes
def collectRight(root, res): if root is None: return
curr = root
temp = []
while not isLeaf(curr):
temp.append(curr.data)
if curr.right is not None:
curr = curr.right
else:
curr = curr.left
for i in reversed(temp):
res.append(i)Function to perform boundary traversal
def boundaryTraversal(root): res = []
if root is None:
return res
# Add root data if it's not a leaf
if not isLeaf(root):
res.append(root.data)
# Collect left boundary
collectLeft(root.left, res)
# Collect leaf nodes
collectLeaves(root, res)
# Collect right boundary
collectRight(root.right, res)
return resif name == "main":
# Hardcoded Binary tree
# 1
# / \
# 2 3
# / \ / \
# 4 5 6 7
# / \
# 8 9
root = Node(1)
root.left = Node(2)
root.right = Node(3)
root.left.left = Node(4)
root.left.right = Node(5)
root.right.left = Node(6)
root.right.right = Node(7)
root.left.right.left = Node(8)
root.left.right.right = Node(9)
boundary = boundaryTraversal(root)
print(" ".join(map(str, boundary)))C#
using System; using System.Collections.Generic;
// Node Structure class Node { public int data; public Node left; public Node right;
public Node(int x)
{
data = x;
left = right = null;
}}
class GFG { static bool isLeaf(Node node) { return node.left == null && node.right == null; }
// Function to collect the left boundary nodes
static void collectLeft(Node root, List<int> res) {
if (root == null)
return;
Node curr = root;
while (!isLeaf(curr))
{
res.Add(curr.data);
if (curr.left != null)
curr = curr.left;
else
curr = curr.right;
}
}
// Function to collect the leaf nodes using Morris Traversal
static void collectLeaves(Node root, List<int> res)
{
Node current = root;
while (current != null)
{
if (current.left == null)
{
// If it's a leaf node
if (current.right == null)
res.Add(current.data);
current = current.right;
}
else
{
// Find the inorder predecessor
Node predecessor = current.left;
while (predecessor.right != null && predecessor.right != current)
{
predecessor = predecessor.right;
}
if (predecessor.right == null)
{
predecessor.right = current;
current = current.left;
}
else
{
// If its predecessor is a leaf node
if (predecessor.left == null)
res.Add(predecessor.data);
predecessor.right = null;
current = current.right;
}
}
}
}
// Function to collect the right boundary nodes
static void collectRight(Node root, List<int> res)
{
if (root == null)
return;
Node curr = root;
List<int> temp = new List<int>();
while (!isLeaf(curr))
{
temp.Add(curr.data);
if (curr.right != null)
curr = curr.right;
else
curr = curr.left;
}
for (int i = temp.Count - 1; i >= 0; --i)
res.Add(temp[i]);
}
// Function to perform boundary traversal
static List<int> boundaryTraversal(Node root)
{
List<int> res = new List<int>();
if (root == null)
return res;
// Add root data if it's not a leaf
if (!isLeaf(root))
res.Add(root.data);
// Collect left boundary
collectLeft(root.left, res);
// Collect leaf nodes
collectLeaves(root, res);
// Collect right boundary
collectRight(root.right, res);
return res;
}
static void Main(string[] args)
{
// Hardcoded Binary tree
// 1
// / \
// 2 3
// / \ / \
// 4 5 6 7
// / \
// 8 9
Node root = new Node(1);
root.left = new Node(2);
root.right = new Node(3);
root.left.left = new Node(4);
root.left.right = new Node(5);
root.right.left = new Node(6);
root.right.right = new Node(7);
root.left.right.left = new Node(8);
root.left.right.right = new Node(9);
List<int> boundary = boundaryTraversal(root);
foreach (int x in boundary)
Console.Write(x + " ");
}}
JavaScript
// Node Structure class Node { constructor(x) { this.data = x; this.left = null; this.right = null; } }
function isLeaf(node) { return node.left === null && node.right === null; }
// Function to collect the left boundary nodes function collectLeft(root, res) { if (root === null) return;
let curr = root;
while (!isLeaf(curr)) {
res.push(curr.data);
if (curr.left !== null)
curr = curr.left;
else
curr = curr.right;
}}
// Function to collect the leaf nodes using Morris Traversal function collectLeaves(root, res) { let current = root;
while (current) {
if (current.left === null) {
// If it's a leaf node
if (current.right === null)
res.push(current.data);
current = current.right;
} else {
// Find the inorder predecessor
let predecessor = current.left;
while (predecessor.right && predecessor.right !== current) {
predecessor = predecessor.right;
}
if (predecessor.right === null) {
predecessor.right = current;
current = current.left;
} else {
// If its predecessor is a leaf node
if (predecessor.left === null)
res.push(predecessor.data);
predecessor.right = null;
current = current.right;
}
}
}}
// Function to collect the right boundary nodes function collectRight(root, res) { if (root === null) return;
let curr = root;
let temp = [];
while (!isLeaf(curr)) {
temp.push(curr.data);
if (curr.right !== null)
curr = curr.right;
else
curr = curr.left;
}
for (let i = temp.length - 1; i >= 0; i--)
res.push(temp[i]);}
// Function to perform boundary traversal function boundaryTraversal(root) { let res = [];
if (root === null)
return res;
// Add root data if it's not a leaf
if (!isLeaf(root))
res.push(root.data);
// Collect left boundary
collectLeft(root.left, res);
// Collect leaf nodes
collectLeaves(root, res);
// Collect right boundary
collectRight(root.right, res);
return res;}
// Driver Code
// Hardcoded Binary tree
// 1
// /
// 2 3
// / \ /
// 4 5 6 7
// /
// 8 9
let root = new Node(1); root.left = new Node(2); root.right = new Node(3);
root.left.left = new Node(4); root.left.right = new Node(5);
root.right.left = new Node(6); root.right.right = new Node(7);
root.left.right.left = new Node(8); root.left.right.right = new Node(9);
let boundary = boundaryTraversal(root); console.log(boundary.join(" "));
`



