Getting Started with Trees: Understanding Depth and Height

Elif İrem Kara Kadyrov
6 min readFeb 2, 2023

--

Welcome to the first part of the guide on trees my fellow readers!

Trees are one of computer science's most fundamental data structures. They are used in a wide range of applications, from file systems and databases to game development and artificial intelligence. In this guide, we will start to cover the topics you need to know about trees to ace your following interview.

In this blog, we will be looking at two basic concepts:

  1. The basic definition and structure of a tree
  2. The concepts of depth and height in a tree

These concepts will be reinforced by related LeetCode problems. Let’s begin, shall we?

What is a tree?

A tree is a hierarchical data structure made from nodes and has a specific shape. Each node in a tree has a value and zero or more children. The topmost node, which has no parent, is called the root, and the nodes with no children are called leaves.

Imagine a tree as a family tree, where each node represents a family member. The root will be the eldest person in the family, and the leaves will be the youngest.

Let’s start with a simple binary tree structure:

 function TreeNode(val, left, right) {
this.val = (val===undefined ? 0 : val)
this.left = (left===undefined ? null : left)
this.right = (right===undefined ? null : right)
}

We can compose a binary tree based on this structure:

let root = new TreeNode(1);
let leftChild = new TreeNode(2);
let rightChild = new TreeNode(3);
root.left = leftChild;
root.right = rightChild;
let leftGrandChild = new TreeNode(4);
let rightGrandChild = null;
leftChild.left = leftGrandChild;
leftChild.right = rightGrandChild;

Our tree will look like this:

                                      1
/ \
2 3
/
4

The Depth and Height Concepts

The depth and height of a tree provide information about the location and arrangement of the nodes in a tree.

For example, in a file system, the root directory can be considered as the root node of a tree, and each subdirectory can be considered as a child node.

The depth of a file represents its location within the directory structure, while the height of the tree represents the maximum number of nested subdirectories. This information can be used to determine the relative location of files within the file system and to determine the maximum number of directories needed to reach a particular file.

Similarly, the same logic can be applied to the tree problems. In a decision tree, each node represents a decision point and the branches represent the possible outcomes.

The depth of a node in the tree represents the number of decision points leading up to that node, while the height of the tree represents the maximum number of decisions that need to be made to reach an outcome. This information can be used to determine the optimal path through the decision tree and to evaluate the overall complexity of the decision-making process.

Depth: It is the number of steps you need to take to reach a specific node from the root. For example, in the tree that we formed earlier, the depth of the root node (1) is 0, the depth of node 2 is 1, and the depth of node 4 is 2.

Height: It’s the maximum depth of any node in the tree. For the tree shown above, the height is 2 (the path from the root node to node 4).

Let’s see the implementation of how we can find the depth and height of the tree in JavaScript:

function TreeNode(val, left, right) {
this.val = (val === undefined ? 0 : val);
this.left = (left === undefined ? null : left);
this.right = (right === undefined ? null : right);
}

function height(node) {
if (node === null) {
return 0;
}
return 1 + Math.max(height(node.left), height(node.right));
}

function depth(node, val, currentDepth) {
if (node === null) {
return 0;
}
if (node.val === val) {
return currentDepth;
}
let left = depth(node.left, val, currentDepth + 1);
let right = depth(node.right, val, currentDepth + 1);
return left || right;
}

The height function calculates the tree's height by recursively finding the maximum height of the left and right subtrees and adding 1 to it. The base case is when the node is null, then we return 0.

The depth function uses a recursive approach to traverse a tree. If the current node is null, it returns 0. If the value of the current node is equal to the target value, it returns the current depth. If not, it calculates the depth of the left and right subtrees by passing in the updated current depth. Finally, the function returns the depth of the left or right subtree if the value exists.

Problems from LeetCode

I have selected some problems that are related to the depth and height of a tree. Let’s see how we can encounter these topics in problems.

111. Minimum Depth of Binary Tree

The question: Given a binary tree, find its minimum depth.

The minimum depth is the number of nodes along the shortest path from the root node down to the nearest leaf node.

Input: root = [3,9,20,null,null,15,7]
Output: 2

The approach: If the root is null, we will return 0. Otherwise, the minimum depth will be calculated as the minimum of left and right subtrees + 1. The function can be called recursively for this purpose.

var minDepth = function(root) {
if (!root) return 0;

if (!root.left && !root.right) return 1;

let left = minDepth(root.left);
let right = minDepth(root.right);

return 1 + Math.min(left || Number.MAX_SAFE_INTEGER,
right || Number.MAX_SAFE_INTEGER);
};

Notes: Number.MAX_SAFE_INTEGER is a constant in JavaScript that represents the maximum safe integer value that can be used in mathematical operations without losing precision.

To find the minimum depth of the entire tree, the minimum depth of the left and right subtrees must be compared. If one of the subtrees is null, it will return 0, and this will be the minimum value. To ensure that 0 is the minimum value, Number.MAX_SAFE_INTEGER is used as a placeholder value for the minimum depth of a non-null subtree.

If the both left and right children of the current node are null (which means a leaf node), we can return 1. This way, the function will not keep recursing through the tree when it has reached a leaf node.

559. Maximum Depth of N-ary Tree

The question: Given an n-ary tree, find its maximum depth.

Input: root = [1,null,3,2,4,null,5,6]
Output: 3

The approach: As you can see, the difference between this and the common depth question is that this tree can have more than two children. Instead of looking for just the left and right children of a tree, we need a function that visits all of the children nodes.

var maxDepth = function(root) {
if(!root) return 0;

let max = 0;
for(let i = 0; i < root.children.length; i++) {
max = Math.max(max, maxDepth(root.children[i]));
}

return 1 + max;
};

The max variable outside the loop is to keep track of the maximum depth and update it if the newly visited children have more depth than the current maximum.

Conclusion

Understanding the basics of trees is crucial for a developer because it helps you understand the foundation of many algorithms, data structures, and computer science concepts.

When you think about it, trees are everywhere! From HTML DOM trees to decision trees in machine learning, they are an essential component of many real-world systems.

Hope this will be a good start for our journey in tree concepts!

--

--