Iterative Segment Tree (Range Minimum Query) - GeeksforGeeks

23 Jun, 2021
We have discussed recursive segment tree implementation. In this post, iterative implementation is discussed.Let us consider the following problem understand Segment Trees.We have an array arr[0 . . . n-1]. We should be able to 1 Find the minimum of elements from index l to r where 0 <= l <= r <= n-1 2 Change value of a specified element of the array to a new value x. We need to do arr[i] = x where 0 <= i <= n-1.Examples:  
Input : 2, 6, 7, 5, 18, 86, 54, 2
        minimum(2, 7)  
        update(3, 4)
        minimum(2, 6) 
Output : Minimum in range 2 to 7 is 2.
         Minimum in range 2 to 6 is 4.
 
The iterative version of the segment tree basically uses the fact, that for an index i, left child = 2 * i and right child = 2 * i + 1 in the tree. The parent for an index i in the segment tree array can be found by parent = i / 2. Thus we can easily travel up and down through the levels of the tree one by one. At first we compute the minimum in the ranges while constructing the tree starting from the leaf nodes and climbing up through the levels one by one. We use the same concept while processing the queries for finding the minimum in a range. Since there are (log n) levels in the worst case, so querying takes log n time. For update of a particular index to a given value we start updating the segment tree starting from the leaf nodes and update all those nodes which are affected by the updation of the current node by gradually moving up through the levels at every iteration. Updation also takes log n time because there we have to update all the levels starting from the leaf node where we update the exact value at the exact index given by the user.  
C++
Java
Python3
C#
Javascript
// CPP Program to implement iterative segment// tree.#include <bits/stdc++.h>#define ll long long using namespace std; void construct_segment_tree(vector<int>& segtree,                           vector<int> &a, int n){    // assign values to leaves of the segment tree    for (int i = 0; i < n; i++)        segtree[n + i] = a[i];        /* assign values to internal nodes      to compute minimum in a given range */    for (int i = n - 1; i >= 1; i--)        segtree[i] = min(segtree[2 * i],                         segtree[2 * i + 1]);} void update(vector<int>& segtree, int pos, int value,                                               int n){    // change the index to leaf node first    pos += n;     // update the value at the leaf node    // at the exact index    segtree[pos] = value;     while (pos > 1) {         // move up one level at a time in the tree        pos >>= 1;         // update the values in the nodes in        // the next higher level        segtree[pos] = min(segtree[2 * pos],                           segtree[2 * pos + 1]);    }} int range_query(vector<int>& segtree, int left, int                                      right, int n){    /*  Basically the left and right indices will move        towards right and left respectively and with        every each next higher level and compute the        minimum at each height. */    // change the index to leaf node first    left += n;    right += n;     // initialize minimum to a very high value    int mi = (int)1e9;     while (left < right) {         // if left index in odd        if (left & 1) {            mi = min(mi, segtree[left]);             // make left index even            left++;        }         // if right index in odd        if (right & 1) {             // make right index even            right--;             mi = min(mi, segtree[right]);        }         // move to the next higher level        left /= 2;        right /= 2;    }    return mi;} // Driver codeint main(){    vector<int> a = { 2, 6, 10, 4, 7, 28, 9, 11, 6, 33 };    int n = a.size();      /* Construct the segment tree by assigning       the values to the internal nodes*/    vector<int> segtree(2 * n);    construct_segment_tree(segtree, a, n);     // compute minimum in the range left to right    int left = 0, right = 5;    cout << "Minimum in range " << left << " to "         << right << " is "<< range_query(segtree, left,                                  right + 1, n) << "\n";     // update the value of index 3 to 1    int index = 3, value = 1;     // a[3] = 1;    // Contents of array : {2, 6, 10, 1, 7, 28, 9, 11, 6, 33}    update(segtree, index, value, n); // point update     // compute minimum in the range left to right    left = 2, right = 6;    cout << "Minimum in range " << left << " to "         << right << " is " << range_query(segtree,                      left, right + 1, n) << "\n";     return 0;}
// Java Program to implement iterative segment// tree.import java.io.*;import java.util.*; class GFG{     static void construct_segment_tree(int[] segtree,                                        int[] a, int n)    {                 // assign values to leaves of the segment tree        for (int i = 0; i < n; i++)            segtree[n + i] = a[i];         /*        * assign values to internal nodes        * to compute minimum in a given range        */        for (int i = n - 1; i >= 1; i--)            segtree[i] = Math.min(segtree[2 * i], segtree[2 * i + 1]);    }     static void update(int[] segtree, int pos, int value, int n)    {         // change the index to leaf node first        pos += n;         // update the value at the leaf node        // at the exact index        segtree[pos] = value;         while (pos > 1)        {             // move up one level at a time in the tree            pos >>= 1;             // update the values in the nodes in            // the next higher level            segtree[pos] = Math.min(segtree[2 * pos],                                segtree[2 * pos + 1]);        }    }     static int range_query(int[] segtree, int left,                           int right, int n)    {                 /*        * Basically the left and right indices will move        * towards right and left respectively and with        * every each next higher level and compute the        * minimum at each height. */        // change the index to leaf node first        left += n;        right += n;         // initialize minimum to a very high value        int mi = (int) 1e9;         while (left < right)        {             // if left index in odd            if ((left & 1) == 1)            {                mi = Math.min(mi, segtree[left]);                 // make left index even                left++;            }             // if right index in odd            if ((right & 1) == 1)            {                 // make right index even                right--;                 mi = Math.min(mi, segtree[right]);            }             // move to the next higher level            left /= 2;            right /= 2;        }        return mi;    }     // Driver Code    public static void main(String[] args)    {        int[] a = {2, 6, 10, 4, 7, 28, 9, 11, 6, 33};        int n = a.length;         /*        * Construct the segment tree by assigning        * the values to the internal nodes        */        int[] segtree = new int[2 * n];        construct_segment_tree(segtree, a, n);         // compute minimum in the range left to right        int left = 0, right = 5;        System.out.printf("Minimum in range %d to %d is %d\n",                           left, right, range_query(segtree,                           left, right + 1, n));         // update the value of index 3 to 1        int index = 3, value = 1;                 // a[3] = 1;        // Contents of array : {2, 6, 10, 1, 7, 28, 9, 11, 6, 33}        update(segtree, index, value, n); // point update         // compute minimum in the range left to right        left = 2;        right = 6;        System.out.printf("Minimum in range %d to %d is %d\n",                           left, right, range_query(segtree,                           left, right + 1, n));    }} // This code is contributed by// sanjeev2552
# Python3 program to implement# iterative segment tree.def construct_segment_tree(segtree, a, n):         # assign values to leaves of    # the segment tree    for i in range(n):        segtree[n + i] = a[i];         # assign values to remaining nodes    # to compute minimum in a given range    for i in range(n - 1, 0, -1):        segtree[i] = min(segtree[2 * i],                         segtree[2 * i + 1])                         def range_query(segtree, left, right, n):    left += n    right += n         """ Basically the left and right indices        will move towards right and left respectively        and with every each next higher level and        compute the minimum at each height change        the index to leaf node first """    mi = 1e9 # initialize minimum to a very high value    while (left < right):        if (left & 1): # if left index in odd                mi = min(mi, segtree[left])                left = left + 1        if (right & 1): # if right index in odd                right -= 1                mi = min(mi, segtree[right])                         # move to the next higher level        left = left // 2        right = right // 2    return mi def update(segtree, pos, value, n):         # change the index to leaf node first    pos += n         # update the value at the leaf node    # at the exact index    segtree[pos] = value    while (pos > 1):                 # move up one level at a time in the tree        pos >>= 1;                 # update the values in the nodes        # in the next higher level        segtree[pos] = min(segtree[2 * pos],                           segtree[2 * pos + 1]) # Driver Code     # Elements in lista = [2, 6, 10, 4, 7, 28, 9, 11, 6, 33]n = len(a) # Construct the segment tree by assigning# the values to the internal nodessegtree = [0 for i in range(2 * n)]construct_segment_tree(segtree, a, n);left = 0right = 5 #compute minimum in the range left to rightprint ("Minimum in range", left, "to", right, "is",        range_query(segtree, left, right + 1, n)) # update the value of index 3 to 1index = 3value = 1 # a[3] = 1;# Contents of array : {2, 6, 10, 1, 7, 28, 9, 11, 6, 33}update(segtree, index, value, n); # point updateleft = 2right = 6 # compute minimum in the range left to rightprint("Minimum in range", left, "to", right, "is",       range_query(segtree, left, right + 1, n))        # This code is contributed by sarthak Raghuwanshi
// C# Program to implement iterative segment// tree.using System; class GFG{     static void construct_segment_tree(int[] segtree,                                        int[] a, int n)    {                 // assign values to leaves of the segment tree        for (int i = 0; i < n; i++)            segtree[n + i] = a[i];         /*        * assign values to internal nodes        * to compute minimum in a given range        */        for (int i = n - 1; i >= 1; i--)            segtree[i] = Math.Min(segtree[2 * i],                            segtree[2 * i + 1]);    }     static void update(int[] segtree, int pos,                        int value, int n)    {         // change the index to leaf node first        pos += n;         // update the value at the leaf node        // at the exact index        segtree[pos] = value;         while (pos > 1)        {             // move up one level at a time in the tree            pos >>= 1;             // update the values in the nodes in            // the next higher level            segtree[pos] = Math.Min(segtree[2 * pos],                                segtree[2 * pos + 1]);        }    }     static int range_query(int[] segtree, int left,                        int right, int n)    {                 /*        * Basically the left and right indices will move        * towards right and left respectively and with        * every each next higher level and compute the        * minimum at each height. */        // change the index to leaf node first        left += n;        right += n;         // initialize minimum to a very high value        int mi = (int) 1e9;         while (left < right)        {             // if left index in odd            if ((left & 1) == 1)            {                mi = Math.Min(mi, segtree[left]);                 // make left index even                left++;            }             // if right index in odd            if ((right & 1) == 1)            {                 // make right index even                right--;                 mi = Math.Min(mi, segtree[right]);            }             // move to the next higher level            left /= 2;            right /= 2;        }        return mi;    }     // Driver Code    public static void Main(String[] args)    {        int[] a = {2, 6, 10, 4, 7, 28, 9, 11, 6, 33};        int n = a.Length;         /*        * Construct the segment tree by assigning        * the values to the internal nodes        */        int[] segtree = new int[2 * n];        construct_segment_tree(segtree, a, n);         // compute minimum in the range left to right        int left = 0, right = 5;        Console.Write("Minimum in range {0} to {1} is {2}\n",                        left, right, range_query(segtree,                        left, right + 1, n));         // update the value of index 3 to 1        int index = 3, value = 1;                 // a[3] = 1;        // Contents of array : {2, 6, 10, 1, 7, 28, 9, 11, 6, 33}        update(segtree, index, value, n); // point update         // compute minimum in the range left to right        left = 2;        right = 6;        Console.Write("Minimum in range {0} to {1} is {2}\n",                        left, right, range_query(segtree,                        left, right + 1, n));    }} // This code is contributed by Rajput-Ji
<script> // Javascript Program to implement iterative segment// tree.function construct_segment_tree(segtree, a, n){         // assign values to leaves of the segment tree    for (var i = 0; i < n; i++)        segtree[n + i] = a[i];    /*    * assign values to internal nodes    * to compute minimum in a given range    */    for (var i = n - 1; i >= 1; i--)        segtree[i] = Math.min(segtree[2 * i],                        segtree[2 * i + 1]);}function update(segtree, pos, value, n){    // change the index to leaf node first    pos += n;         // update the value at the leaf node    // at the exact index    segtree[pos] = value;    while (pos > 1)    {        // move up one level at a time in the tree        pos >>= 1;                 // update the values in the nodes in        // the next higher level        segtree[pos] = Math.min(segtree[2 * pos],                            segtree[2 * pos + 1]);    }}function range_query(segtree, left, right, n){         /*    * Basically the left and right indices will move    * towards right and left respectively and with    * every each next higher level and compute the    * minimum at each height. */    // change the index to leaf node first    left += n;    right += n;    // initialize minimum to a very high value    var mi = 1000000000;    while (left < right)    {             // if left index in odd        if ((left & 1) == 1)        {            mi = Math.min(mi, segtree[left]);            // make left index even            left++;        }        // if right index in odd        if ((right & 1) == 1)        {            // make right index even            right--;            mi = Math.min(mi, segtree[right]);        }        // move to the next higher level        left /= 2;        right /= 2;    }    return mi;} // Driver Codevar a = [2, 6, 10, 4, 7, 28, 9, 11, 6, 33];var n = a.length;/** Construct the segment tree by assigning* the values to the internal nodes*/var segtree = Array(2*n).fill(0);construct_segment_tree(segtree, a, n); // compute minimum in the range left to rightvar left = 0, right = 5;document.write(`Minimum in range ${left} to ${right} is ${range_query(segtree,left, right + 1, n)}<br>`) // update the value of index 3 to 1var index = 3, value = 1; // a[3] = 1;// Contents of array : {2, 6, 10, 1, 7, 28, 9, 11, 6, 33}update(segtree, index, value, n); // point update // compute minimum in the range left to rightleft = 2;right = 6;document.write(`Minimum in range ${left} to ${right} is ${range_query(segtree, left, right + 1, n)}<br>`); // This code is contributed by rutvik_56.</script>
Minimum in range 0 to 5 is 2
Minimum in range 2 to 6 is 1
 
Time Complexity :(n log n) Auxiliary Space : (n) 
Sarthak Raghuwanshi
sanjeev2552
Rajput-Ji
rutvik_56
array-range-queries
Segment-Tree
Advanced Data Structure
Tree
Tree
Segment-Tree
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.
Comments
Old Comments
Extendible Hashing (Dynamic approach to DBMS)
Ternary Search Tree
Proof that Dominant Set of a Graph is NP-Complete
2-3 Trees | (Search, Insert and Deletion)
Advantages of Trie Data Structure
Tree Traversals (Inorder, Preorder and Postorder)
Binary Tree | Set 1 (Introduction)
Level Order Binary Tree Traversal
Inorder Tree Traversal without Recursion
Binary Tree | Set 3 (Types of Binary Tree)