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:

  1. **Left Boundary: The nodes on the left edge of the tree, excluding the leaf nodes.
  2. **Leaf Nodes: All the leaf nodes from left to right.
  3. **Right Boundary: The nodes on the right edge of the tree, excluding the leaf nodes, traversed in bottom-up order.

**Note:

**Input :

1-

**Output : [1, 2, 4, 8, 9, 6, 7, 3]
**Explanation:

420046670

**Input :

3-

**Output : [1, 4, 3, 2]
**Explanation:

420046671

Try It Yourselfredirect icon

Table of Content

[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 res

if 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.right

Function 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.right

Function 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 res

if 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(" "));

`