← Back to DSA Course | Chapter 11: Trees | Lesson 9 of 10

Tree Views Left Right Top Bottom

Tree views are like looking at a tree from the left, right, top or bottom and writing down only the branches you can see from that side.
Syntax
markup
from collections import deque
queue = deque([root])
while queue:
    size = len(queue)
    for i in range(size):
        node = queue.popleft()
        if i == 0:
            left_view.append(node.value)    # first node of level
        # enqueue children

Left View

The left view of a tree lists the first node visible from each level when looking at the tree from the left side — this is the leftmost node encountered at every depth, one per level.

Example: Left View

#include <iostream>
#include <queue>
using namespace std;
struct Node { int val; Node *left, *right; };
int main() {
    Node l={2,nullptr,nullptr}, r={3,nullptr,nullptr};
    Node root={1,&l,&r};
    queue<Node*> q; q.push(&root);
    while (!q.empty()) {
        int n = q.size();
        for (int i = 0; i < n; i++) {
            Node* node = q.front(); q.pop();
            if (i == 0) cout << node->val << " ";
            if (node->left) q.push(node->left);
            if (node->right) q.push(node->right);
        }
    }
    return 0;
}
import java.util.*;
public class Main {
    static class Node { int val; Node left, right; Node(int v){val=v;} }
    public static void main(String[] args) {
        Node root = new Node(1);
        root.left = new Node(2); root.right = new Node(3);
        Queue<Node> q = new LinkedList<>(); q.add(root);
        while (!q.isEmpty()) {
            int n = q.size();
            for (int i = 0; i < n; i++) {
                Node node = q.poll();
                if (i == 0) System.out.print(node.val + " ");
                if (node.left != null) q.add(node.left);
                if (node.right != null) q.add(node.right);
            }
        }
    }
}
from collections import deque

class Node:
    def __init__(self, val):
        self.val = val; self.left = None; self.right = None

root = Node(1)
root.left = Node(2); root.right = Node(3)
q = deque([root])
while q:
    n = len(q)
    for i in range(n):
        node = q.popleft()
        if i == 0:
            print(node.val, end=" ")
        if node.left: q.append(node.left)
        if node.right: q.append(node.right)
#include <stdio.h>
#include <stddef.h>
struct Node { int val; struct Node *left, *right; };
struct Node* q[10]; int head=0, tail=0;
int main() {
    struct Node l={2,NULL,NULL}, r={3,NULL,NULL};
    struct Node root={1,&l,&r};
    q[tail++] = &root;
    while (head < tail) {
        int n = tail - head;
        for (int i = 0; i < n; i++) {
            struct Node* node = q[head++];
            if (i == 0) printf("%d ", node->val);
            if (node->left) q[tail++] = node->left;
            if (node->right) q[tail++] = node->right;
        }
    }
    return 0;
}

Right View

The right view is the mirror of the left view: the last node visible from each level when looking from the right side, meaning the rightmost node encountered at every depth.

Example: Right View

#include <iostream>
#include <queue>
using namespace std;
struct Node { int val; Node *left, *right; };
int main() {
    Node l={2,nullptr,nullptr}, r={3,nullptr,nullptr};
    Node root={1,&l,&r};
    queue<Node*> q; q.push(&root);
    while (!q.empty()) {
        int n = q.size();
        for (int i = 0; i < n; i++) {
            Node* node = q.front(); q.pop();
            if (i == n - 1) cout << node->val << " ";
            if (node->left) q.push(node->left);
            if (node->right) q.push(node->right);
        }
    }
    return 0;
}
import java.util.*;
public class Main {
    static class Node { int val; Node left, right; Node(int v){val=v;} }
    public static void main(String[] args) {
        Node root = new Node(1);
        root.left = new Node(2); root.right = new Node(3);
        Queue<Node> q = new LinkedList<>(); q.add(root);
        while (!q.isEmpty()) {
            int n = q.size();
            for (int i = 0; i < n; i++) {
                Node node = q.poll();
                if (i == n - 1) System.out.print(node.val + " ");
                if (node.left != null) q.add(node.left);
                if (node.right != null) q.add(node.right);
            }
        }
    }
}
from collections import deque

class Node:
    def __init__(self, val):
        self.val = val; self.left = None; self.right = None

root = Node(1)
root.left = Node(2); root.right = Node(3)
q = deque([root])
while q:
    n = len(q)
    for i in range(n):
        node = q.popleft()
        if i == n - 1:
            print(node.val, end=" ")
        if node.left: q.append(node.left)
        if node.right: q.append(node.right)
#include <stdio.h>
#include <stddef.h>
struct Node { int val; struct Node *left, *right; };
struct Node* q[10]; int head=0, tail=0;
int main() {
    struct Node l={2,NULL,NULL}, r={3,NULL,NULL};
    struct Node root={1,&l,&r};
    q[tail++] = &root;
    while (head < tail) {
        int n = tail - head;
        for (int i = 0; i < n; i++) {
            struct Node* node = q[head++];
            if (i == n - 1) printf("%d ", node->val);
            if (node->left) q[tail++] = node->left;
            if (node->right) q[tail++] = node->right;
        }
    }
    return 0;
}

Top View

The top view lists the first node encountered at each horizontal distance from the root when the tree is projected onto a horizontal line — nodes directly above or below each other (same horizontal distance) only show their topmost one.

Example: Top View

#include <iostream>
#include <map>
using namespace std;
struct Node { int val; Node *left, *right; };
void topView(Node* n, int hd, map<int,int>& seen) {
    if (!n) return;
    if (seen.find(hd) == seen.end()) seen[hd] = n->val;
    topView(n->left, hd - 1, seen);
    topView(n->right, hd + 1, seen);
}
int main() {
    Node l={2,nullptr,nullptr}, r={3,nullptr,nullptr};
    Node root={1,&l,&r};
    map<int,int> seen;
    topView(&root, 0, seen);
    for (auto& p : seen) cout << p.second << " ";
    return 0;
}
import java.util.*;
public class Main {
    static class Node { int val; Node left, right; Node(int v){val=v;} }
    static void topView(Node n, int hd, TreeMap<Integer,Integer> seen) {
        if (n == null) return;
        seen.putIfAbsent(hd, n.val);
        topView(n.left, hd - 1, seen);
        topView(n.right, hd + 1, seen);
    }
    public static void main(String[] args) {
        Node root = new Node(1);
        root.left = new Node(2); root.right = new Node(3);
        TreeMap<Integer,Integer> seen = new TreeMap<>();
        topView(root, 0, seen);
        for (int v : seen.values()) System.out.print(v + " ");
    }
}
class Node:
    def __init__(self, val):
        self.val = val; self.left = None; self.right = None

def top_view(n, hd, seen):
    if n is None:
        return
    if hd not in seen:
        seen[hd] = n.val
    top_view(n.left, hd - 1, seen)
    top_view(n.right, hd + 1, seen)

root = Node(1)
root.left = Node(2); root.right = Node(3)
seen = {}
top_view(root, 0, seen)
for k in sorted(seen):
    print(seen[k], end=" ")
#include <stdio.h>
#include <stddef.h>
struct Node { int val; struct Node *left, *right; };
int seenVal[20], seenSet[20];
void topView(struct Node* n, int hd) {
    if (!n) return;
    if (!seenSet[hd+10]) { seenSet[hd+10] = 1; seenVal[hd+10] = n->val; }
    topView(n->left, hd - 1);
    topView(n->right, hd + 1);
}
int main() {
    struct Node l={2,NULL,NULL}, r={3,NULL,NULL};
    struct Node root={1,&l,&r};
    topView(&root, 0);
    for (int i = 0; i < 20; i++) if (seenSet[i]) printf("%d ", seenVal[i]);
    return 0;
}

Bottom View

The bottom view is the mirror of the top view: instead of the first node seen at each horizontal distance, it keeps the last (bottommost) one, since lower nodes visually overwrite higher ones at the same horizontal position.

Example: Bottom View

#include <iostream>
#include <map>
using namespace std;
struct Node { int val; Node *left, *right; };
void bottomView(Node* n, int hd, map<int,int>& seen) {
    if (!n) return;
    seen[hd] = n->val;
    bottomView(n->left, hd - 1, seen);
    bottomView(n->right, hd + 1, seen);
}
int main() {
    Node l={2,nullptr,nullptr}, r={3,nullptr,nullptr};
    Node root={1,&l,&r};
    map<int,int> seen;
    bottomView(&root, 0, seen);
    for (auto& p : seen) cout << p.second << " ";
    return 0;
}
import java.util.*;
public class Main {
    static class Node { int val; Node left, right; Node(int v){val=v;} }
    static void bottomView(Node n, int hd, TreeMap<Integer,Integer> seen) {
        if (n == null) return;
        seen.put(hd, n.val);
        bottomView(n.left, hd - 1, seen);
        bottomView(n.right, hd + 1, seen);
    }
    public static void main(String[] args) {
        Node root = new Node(1);
        root.left = new Node(2); root.right = new Node(3);
        TreeMap<Integer,Integer> seen = new TreeMap<>();
        bottomView(root, 0, seen);
        for (int v : seen.values()) System.out.print(v + " ");
    }
}
class Node:
    def __init__(self, val):
        self.val = val; self.left = None; self.right = None

def bottom_view(n, hd, seen):
    if n is None:
        return
    seen[hd] = n.val
    bottom_view(n.left, hd - 1, seen)
    bottom_view(n.right, hd + 1, seen)

root = Node(1)
root.left = Node(2); root.right = Node(3)
seen = {}
bottom_view(root, 0, seen)
for k in sorted(seen):
    print(seen[k], end=" ")
#include <stdio.h>
#include <stddef.h>
struct Node { int val; struct Node *left, *right; };
int seenVal[20], seenSet[20];
void bottomView(struct Node* n, int hd) {
    if (!n) return;
    seenSet[hd+10] = 1; seenVal[hd+10] = n->val;
    bottomView(n->left, hd - 1);
    bottomView(n->right, hd + 1);
}
int main() {
    struct Node l={2,NULL,NULL}, r={3,NULL,NULL};
    struct Node root={1,&l,&r};
    bottomView(&root, 0);
    for (int i = 0; i < 20; i++) if (seenSet[i]) printf("%d ", seenVal[i]);
    return 0;
}

View Practice

All four views are most naturally solved with a level-order (BFS) traversal, tracking either the level number (for left/right views) or horizontal distance from the root (for top/bottom views) as nodes are processed.

Example: View Practice

#include <iostream>
using namespace std;
int main() {
    cout << "Left/Right views use level-order BFS tracking level index; Top/Bottom views use DFS/BFS tracking horizontal distance" << endl;
    return 0;
}
public class Main {
    public static void main(String[] args) {
        System.out.println("Left/Right views use level-order BFS tracking level index; Top/Bottom views use DFS/BFS tracking horizontal distance");
    }
}
print("Left/Right views use level-order BFS tracking level index; Top/Bottom views use DFS/BFS tracking horizontal distance")
#include <stdio.h>
int main() {
    printf("Left/Right views use level-order BFS tracking level index; Top/Bottom views use DFS/BFS tracking horizontal distance\n");
    return 0;
}
Related Topics
{# common_mistakes/chapter_summary/browser_support: on Hindi pages the view already swaps in the hi_ translation fields (or blanks these out if untranslated), so this renders correctly for both languages without a lang_code check here. #}
Common Mistakes
  1. Using a DFS and taking the first node found at each depth without processing the left child first, so the wrong node appears in the left view.
  2. Forgetting to track horizontal distance, so the top and bottom view mix up nodes on different columns.
  3. Overwriting the top view entry with later nodes instead of keeping the first, which gives the bottom view.

Login to run this code

C/C++/Java/PHP execution requires a free account. Your code is saved — you'll land right back in the editor after logging in.