TopicsTreeTree Views
📖

Tree Views

Tree
~20 min read
5 practice problems

Tree Views

Overview

Tree views refer to different ways of visualizing and traversing a tree data structure. Understanding tree views is crucial for solving various tree-related problems in coding interviews and competitive programming.

Key Concepts

1. Vertical Order Traversal

Vertical order traversal groups nodes based on their column position in the tree. Each node is assigned a column index:

  • Root node has column index 0
  • Left child of a node at column c has column c - 1
  • Right child of a node at column c has column c + 1

Example:

       3
      / \
     9   20
        / \
       15  7

Vertical order traversal would group nodes as:

  • Column -1: [9]
  • Column 0: [3, 15]
  • Column 1: [20]
  • Column 2: [7]

2. Level Order Traversal

Level order traversal processes nodes level by level from left to right.

3. Top View of a Binary Tree

The top view shows only the first node encountered when looking at the tree from the top. It requires identifying nodes that are visible from the top perspective.

4. Bottom View of a Binary Tree

The bottom view shows only the last node encountered at each horizontal level when looking from the top.

Common Operations and Algorithms

Vertical Order Traversal Implementation

// Definition for a binary tree node
interface TreeNode {
  val: number;
  left: TreeNode | null;
  right: TreeNode | null;
}

function verticalOrder(root: TreeNode | null): number[][] {
  if (!root) return [];

  const result: number[][] = [];
  const columnMap = new Map<number, number[]>();
  
  // BFS with column tracking
  const queue: [TreeNode, number][] = [[root, 0]];
  
  while (queue.length > 0) {
    const [node, column] = queue.shift()!;
    
    if (!columnMap.has(column)) {
      columnMap.set(column, []);
    }
    
    columnMap.get(column)!.push(node.val);
    
    // Add children with updated columns
    if (node.left) {
      queue.push([node.left, column - 1]);
    }
    
    if (node.right) {
      queue.push([node.right, column + 1]);
    }
  }

  // Sort columns and build result
  const sortedColumns = Array.from(columnMap.keys()).sort((a, b) => a - b);
  for (const col of sortedColumns) {
    result.push(columnMap.get(col)!);
  }

  return result;
}

Top View Implementation

function topView(root: TreeNode | null): number[] {
  if (!root) return [];

  const result: number[] = [];
  const columnMap = new Map<number, TreeNode>();
  
  const queue: [TreeNode, number][] = [[root, 0]];
  
  while (queue.length > 0) {
    const [node, column] = queue.shift()!;
    
    // If no node exists at this column, add it
    if (!columnMap.has(column)) {
      columnMap.set(column, node);
    }
    
    // Add children
    if (node.left) {
      queue.push([node.left, column - 1]);
    }
    
    if (node.right) {
      queue.push([node.right, column + 1]);
    }
  }

  // Build result in left-to-right order
  const sortedColumns = Array.from(columnMap.keys()).sort((a, b) => a - b);
  for (const col of sortedColumns) {
    result.push(columnMap.get(col)!.val);
  }

  return result;
}

Bottom View Implementation

function bottomView(root: TreeNode | null): number[] {
  if (!root) return [];

  const result: number[] = [];
  const columnMap = new Map<number, TreeNode>();
  
  const queue: [TreeNode, number][] = [[root, 0]];
  
  while (queue.length > 0) {
    const [node, column] = queue.shift()!;
    
    // Always update with the latest node at this column
    columnMap.set(column, node);
    
    // Add children
    if (node.left) {
      queue.push([node.left, column - 1]);
    }
    
    if (node.right) {
      queue.push([node.right, column + 1]);
    }
  }

  // Build result in left-to-right order
  const sortedColumns = Array.from(columnMap.keys()).sort((a, b) => a - b);
  for (const col of sortedColumns) {
    result.push(columnMap.get(col)!.val);
  }

  return result;
}

Time and Space Complexity Analysis

Vertical Order Traversal:

  • Time Complexity: O(N), where N is the number of nodes in the tree
  • Space Complexity: O(W × N), where W is the width of the tree (maximum nodes in any column)

Top View:

  • Time Complexity: O(N), where N is the number of nodes in the tree
  • Space Complexity: O(W × N), where W is the maximum width of the tree

Bottom View:

  • Time Complexity: O(N), where N is the number of nodes in the tree
  • Space Complexity: O(W × N), where W is the maximum width of the tree

Common Mistakes to Avoid

  1. Incorrect Column Assignment: Not properly assigning column indices to left and right children
  2. Ignoring Node Values: Focusing only on structure instead of node values in views
  3. Misunderstanding Tree Levels: Confusing level order with column order in traversals
  4. Not Using BFS for Level Order: Trying to implement level order with DFS which can cause incorrect ordering
  5. Edge Cases: Not handling null trees or single node trees correctly

Real-World Applications

  1. Display Layouts: Web page layouts where elements are arranged in columns based on their content structure
  2. Data Visualization: Representing hierarchical data in columnar formats
  3. Database Query Optimization: Understanding query execution plans in tree-based database structures
  4. Network Visualization: Displaying network topology with logical grouping of nodes
  5. IDE Code Navigation: Showing methods or classes in a hierarchical view with columnar organization

Practice Strategy

When practicing tree views:

  1. Start with simple examples to understand column assignments
  2. Practice vertical order traversal on various tree structures
  3. Move to top and bottom view problems with increasing complexity
  4. Focus on handling edge cases like null trees and single nodes
  5. Try to optimize space usage by avoiding unnecessary data structures