
Data Structure
Networking
RDBMS
Operating System
Java
MS Excel
iOS
HTML
CSS
Android
Python
C Programming
C++
C#
MongoDB
MySQL
Javascript
PHP
- Selected Reading
- UPSC IAS Exams Notes
- Developer's Best Practices
- Questions and Answers
- Effective Resume Writing
- HR Interview Questions
- Computer Glossary
- Who is Who
C++ Program to Implement Interval Tree
What is an Interval Tree?
An interval tree is a tree data structure that stores intervals. It helps us to efficiently find all intervals that overlap with a specific interval or point.
The purpose is to enhance a self-balancing Binary Search Tree (BST) known as Interval Tree, which is similar to Red Black Tree, AVL Tree, and so on, with a set of intervals so that all operations can be performed in O(log n) time.
Every node of interval trees stores the following details:
- i: An interval which is represented as a pair [start, end].
- max: The maximum height in subtree rooted with this node.
The low value of an interval provides a key to maintaining order in BST. The insert and delete operation are similar as those used in self-balancing BST.
Let's see an Interval Tree Diagram to understand precisely:

Implement Interval Tree in C++
We have given a set of intervals where each interval contains two values low and high, which specify the start and end time of the interval. Our task is to perform the following operation in the interval tree:
- Add an Interval
- Remove an Interval
- Given an interval y, find if y overlaps with any of the existing intervals.
How to find if the given interval overlaps with existing interval?
- If y overlaps with root's interval, return the root's interval.
- If the left child of the root is not empty and the maximum in the left child is greater than the minimum value of y, then recurse to the left child.
- Else recurse for right child.
Algorithm
Let the interval be searched for y. We need to prove this in for following two cases:
Case 1: One of the following conditions must be true. When we visit the right subtree.
- There is an overlap in the right subtree: This is fine as we need to return one overlapping interval.
- There is no overlap in either subtree: We go to the right subtree only when either the left is NULL or the maximum value in the left is smaller than x.low. So the interval cannot be present in the left subtree.
Case 2: One of the following conditions must be true. When we visit the left subtree.
- There is an overlap in the left subtree: This is fine as we need to return one overlapping interval.
- There is no overlap in either subtree: This is the most important part. We need to look over the following facts:
- We went to the left subtree because x.low <= max in the left subtree.
- max in the left subtree is a high of one of the intervals let us say [a, max] in the left subtree.
- Since x doesn't overlap with any node in the left subtree x.high must be smaller than 'a'.
- All nodes in BST are ordered by low value, so all nodes in right subtree must have a low value greater than 'a'.
- From the above two facts, we can say all intervals in the right subtree have a low value greater than x.high. So x cannot overlap with any interval in the right subtree.
Implementation of Interval Tree
The following C++ example demonstrates the implementation of the interval tree:
#include <iostream> using namespace std; // Structure to represent an interval struct Interval { int low, high; }; // Structure to represent a node in Interval Search Tree struct Node { Interval * i; int max; Node * left, * right; }; Node * newNode(Interval i) { Node * temp = new Node; temp -> i = new Interval(i); temp -> max = i.high; temp -> left = temp -> right = nullptr; return temp; }; Node * insert(Node * root, Interval i) { // Base case: Tree is empty, new node becomes root if (root == nullptr) return newNode(i); // Get low value of interval at root int l = root -> i -> low; // If root's low value is smaller, // then new interval goes to left subtree if (i.low < l) root -> left = insert(root -> left, i); // Else, new node goes to right subtree. else root -> right = insert(root -> right, i); // Update the max value of this ancestor if needed if (root -> max < i.high) root -> max = i.high; return root; } bool isOverlapping(Interval i1, Interval i2) { if (i1.low <= i2.high && i2.low <= i1.high) return true; return false; } Interval * overlapSearch(Node * root, Interval i) { // Base Case, tree is empty if (root == nullptr) return nullptr; // If given interval overlaps with root if (isOverlapping( * (root -> i), i)) return root -> i; if (root -> left != nullptr && root -> left -> max >= i.low) return overlapSearch(root -> left, i); // Else interval can only overlap with right subtree return overlapSearch(root -> right, i); } void inorder(Node * root) { if (root == nullptr) return; inorder(root -> left); cout << "[" << root -> i -> low << ", " << root -> i -> high << "]" << " max = " << root -> max << endl; inorder(root -> right); } int main() { Interval ints[] = {{15, 20}, {10, 30}, {17, 22}, {5, 20}, {12, 25}, {20, 30} }; int n = sizeof(ints) / sizeof(ints[0]); Node * root = nullptr; for (int i = 0; i < n; i++) root = insert(root, ints[i]); cout << "Inorder traversal of constructed Interval Tree is\n"; inorder(root); Interval y = {4, 5}; cout << "\nSearching for interval [" << y.low << "," << y.high << "]"; Interval * res = overlapSearch(root, y); if (res == nullptr) cout << "\nNo Overlapping Interval"; else cout << "\nOverlaps with [" << res -> low << ", " << res -> high << "]"; return 0; }
Following is the data of the interval tree:
Inorder traversal of constructed Interval Tree is [5, 20] max = 20 [10, 30] max = 30 [12, 25] max = 25 [15, 20] max = 30 [17, 22] max = 30 [20, 30] max = 30 Searching for interval [4,5] Overlaps with [5, 20]