Trees Interview Questions & Tips for Senior Engineers

Trees Interview Questions & Tips

By Kenny Polyak | Last updated: June 18, 2024

What is a Tree?

A tree is a hierarchical data structure in computer science consisting of nodes connected by edges. Each node is an element which can store data, representing some scalar value or a key, and the edges contained in that node, representing references to other nodes.

In the most general sense, trees are simply directed acyclic graphs (DAGs) where each node can only have a single other node pointing to it, containing N nodes and N-1 edges. As a hierarchical structure, the topmost node in a tree is called the root node, which has no parent. Every other node in the tree has exactly one parent node and contains connections to an arbitrary number of child nodes; a node that has no children is called a leaf node.

Node Structure

There is no superstructure that can randomly access any particular node in the tree. Instead, trees are inherently recursive: each child of a node is a subtree in itself. When handling trees in software engineering, we usually pass around a reference to the root, from which we can access and manipulate the tree data.

Here's an example of tree node definition:

Java

class TreeNode {
    Integer data = null;
    List<TreeNode> children = new ArrayList<TreeNode>();

TreeNode(Integer value) {
        data = value;
    }
}

Typically, children don't have references to their parents. While this is a possible modification to make on the tree node if the need justifies the extra space, it is rarely done given that the tree is almost always traversed from the root. To learn more about graph and tree traversal algorithms, read about Depth-First Search and Breadth-First Search.

Different Types of Trees

Trees can be tall or wide and everything in between. Since the only restriction on a tree is that the edges are directed and there are no cycles, we can find really tall trees where each node only has one child, or really wide trees where each node has thousands of children.

Trees can have rulesets that enforce the order of nodes on insertion, or they can be randomly built top-down.

By applying specific rulesets to trees, we can define different subtypes with their own advantages and tradeoffs. Typically, these subtypes enforce some criteria related to the height of the tree - the height of a tree is the number of edges in the longest path from the root to a leaf - or to the order that tree nodes must be in.

There are many types of tree implementations, each with their own set of rules and advantages. Below are a just a few examples, with links to further discussion for the tree types we see most often in interviews:

Common Operations on Trees

Although the implementation of these operations will differ greatly based on the type of tree, let's look at the simplest case with an unbalanced N-ary tree - this is a tree without any constraints on the positions of nodes or the number of children per node.

Insert

If there are no constraints on where a node needs to be in a tree, then insertion can be as simple as finding a leaf and adding it as a new child. Below we implement a version of insert where we add the new node as a child to a specific parent.

Java

public static void insertNode(TreeNode root, Integer parentValue, Integer newValue) {
  if (root == null) return;
  if (root.val == parentValue) {
    TreeNode newNode = new TreeNode(newValue);
    root.children.add(newNode);
    return;
  }
  for (TreeNode child: root.children) {
    insertNode(child, parentValue, newValue);
  }
}

Basic Search

Searching in a tree is often explored in terms of traversal algorithms, as these will determine the path taken to search. But in its simplest form, searching in a tree is merely a recursive function - taking advantage of the recursive nature of a tree - that calls itself on each child of a node until the target node is found.

Java

 public static TreeNode searchNode(TreeNode root, Integer target) {
        if (root == null || root.val == target) {
            return root;
        }
        for (TreeNode child : root.children) {
            TreeNode result = searchNode(child, target);
            if (result != null) {
                return result;
            }
        }
        return null;
    }

Delete

Deleting nodes from a tree is sometimes considered an advanced topic, especially when we want to preserve subtrees or adhere to constraints on the tree structure itself. We won't be diving into those here. But, if we want to delete an entire subtree, it's as easy as performing the searchNode method above, and once the target is identified, removing it from the list of children from its parent.

When to Use Trees In Technical Interviews

Trees come up often in technical interview questions because they’re the right amount of difficulty to challenge candidates without taking an unreasonable amount of time for those who understand them. As a result, trees come up in both coding and system design interviews.

Using Trees in Coding Interviews

The most common tree questions involve either manipulation or traversal of trees. Manipulation can look like building a tree, converting a tree from one format to another, converting a linked list to a tree, inserting/removing nodes from a tree, and the like. These really test that you thoroughly understand how the data is structured.

Tree traversals generally involve iterating over the tree or searching for data in the tree. This is where we will use tools like depth-first search (DFS) and breadth-first search (BFS) to our advantage.

Most tree interview problems will explicitly have a tree data structure as an input. These are usually cases where we'll be asked to traverse the tree, but it's also important to be familiar with adding and deleting nodes from a tree.

Common Trees interview Questions

Finally, there are problems where the use of a tree is not so obvious. One common example is using a trie to find string prefixes. If a problem asks us to find strings by their prefix, for example when looking up a term in a dictionary or when implementing an autocomplete tool, then tries are inherently a great way to do that.

Using Trees in System Design Interviews

Here are some examples of where trees are commonly used:

  1. File Systems: Many file systems, such as the hierarchical file systems used in operating systems, utilize tree structures. Directories and subdirectories can be represented as nodes in a tree.
  2. Search Engines: Search engines use tree-based indexing structures like tries to efficiently store and retrieve data related to keywords or phrases.
  3. User Interfaces: Tree structures are used in various user interface components, such as menus, navigation bars, and organization charts. They enable hierarchical representation and navigation of elements.
  4. Compilers: Control flow graphs (CFGs) and other tree-based structures are used in compiler optimizations to analyze program flow and optimize code generation. Trees can also be used to map dependencies.
  5. XML/HTML Parsing: Tree structures are used in parsing and representing XML and HTML documents. The Document Object Model (DOM) represents these documents as trees, allowing for efficient manipulation and traversal.

Common Mistakes in Interviews Featuring Trees

Clarifying Questions to Ask Your Interviewer About Trees

  1. Can we prioritize time complexity over space? All data structures involve some kind of tradeoff, and trees are no different.
  2. How frequently will tree operations be performed? Knowing if the problem will be more read or write heavy will help inform the approach.
  3. What operations need to be supported? If you'll be implementing a tree, be sure to ask your interviewer what operations to prioritize during the interview.
  4. What are the characteristics of the input tree? Be sure to determine if there are any constraints that the input tree adheres to, such as balancing or sorting.
  5. Is the input tree an n-ary tree, a binary tree or a binary search tree? Be sure to ask your interviewer if the input tree is a specific type of tree.