C Program to Implement Segment Tree

This is a C Program to implement segment tree. We have an array arr[0 . . . n-1]. We should be able to
1. Find the sum of elements from index l to r where 0 <= l <= r <= n-1 2. Change value of a specified element of the array arr[i] = x where 0 <= i <= n-1. A simple solution is to run a loop from l to r and calculate sum of elements in given range. To update a value, simply do arr[i] = x. The first operation takes O(n) time and second operation takes O(1) time. Here is source code of the C Program to Implement Segment Tree. The C program is successfully compiled and run on a Linux system. The program output is also shown below.
  1. #include <stdio.h>
  2. #include <math.h>
  3.  
  4. // A utility function to get the middle index from corner indexes.
  5. int getMid(int s, int e) {
  6.     return s + (e - s) / 2;
  7. }
  8.  
  9. int getSumUtil(int *st, int ss, int se, int qs, int qe, int index) {
  10.     // If segment of this node is a part of given range, then return the
  11.     // sum of the segment
  12.     if (qs <= ss && qe >= se)
  13.         return st[index];
  14.  
  15.     // If segment of this node is outside the given range
  16.     if (se < qs || ss > qe)
  17.         return 0;
  18.  
  19.     // If a part of this segment overlaps with the given range
  20.     int mid = getMid(ss, se);
  21.     return getSumUtil(st, ss, mid, qs, qe, 2 * index + 1) + getSumUtil(st,
  22.             mid + 1, se, qs, qe, 2 * index + 2);
  23. }
  24.  
  25. void updateValueUtil(int *st, int ss, int se, int i, int diff, int index) {
  26.     // Base Case: If the input index lies outside the range of this segment
  27.     if (i < ss || i > se)
  28.         return;
  29.  
  30.     // If the input index is in range of this node, then update the value
  31.     // of the node and its children
  32.     st[index] = st[index] + diff;
  33.     if (se != ss) {
  34.         int mid = getMid(ss, se);
  35.         updateValueUtil(st, ss, mid, i, diff, 2 * index + 1);
  36.         updateValueUtil(st, mid + 1, se, i, diff, 2 * index + 2);
  37.     }
  38. }
  39.  
  40. void updateValue(int arr[], int *st, int n, int i, int new_val) {
  41.     // Check for erroneous input index
  42.     if (i < 0 || i > n - 1) {
  43.         printf("Invalid Input");
  44.         return;
  45.     }
  46.  
  47.     // Get the difference between new value and old value
  48.     int diff = new_val - arr[i];
  49.  
  50.     // Update the value in array
  51.     arr[i] = new_val;
  52.  
  53.     // Update the values of nodes in segment tree
  54.     updateValueUtil(st, 0, n - 1, i, diff, 0);
  55. }
  56.  
  57. int getSum(int *st, int n, int qs, int qe) {
  58.     // Check for erroneous input values
  59.     if (qs < 0 || qe > n - 1 || qs > qe) {
  60.         printf("Invalid Input");
  61.         return -1;
  62.     }
  63.  
  64.     return getSumUtil(st, 0, n - 1, qs, qe, 0);
  65. }
  66.  
  67. int constructSTUtil(int arr[], int ss, int se, int *st, int si) {
  68.     // If there is one element in array, store it in current node of
  69.     // segment tree and return
  70.     if (ss == se) {
  71.         st[si] = arr[ss];
  72.         return arr[ss];
  73.     }
  74.  
  75.     // If there are more than one elements, then recur for left and
  76.     // right subtrees and store the sum of values in this node
  77.     int mid = getMid(ss, se);
  78.     st[si] = constructSTUtil(arr, ss, mid, st, si * 2 + 1) + constructSTUtil(
  79.             arr, mid + 1, se, st, si * 2 + 2);
  80.     return st[si];
  81. }
  82.  
  83. int *constructST(int arr[], int n) {
  84.     // Allocate memory for segment tree
  85.     int x = (int) (ceil(log2(n))); //Height of segment tree
  86.     int max_size = 2 * (int) pow(2, x) - 1; //Maximum size of segment tree
  87.     int *st = new int[max_size];
  88.  
  89.     // Fill the allocated memory st
  90.     constructSTUtil(arr, 0, n - 1, st, 0);
  91.  
  92.     // Return the constructed segment tree
  93.     return st;
  94. }
  95.  
  96. int main() {
  97.     int arr[] = { 1, 3, 5, 7, 9, 11 };
  98.     int n = sizeof(arr) / sizeof(arr[0]);
  99.  
  100.     // Build segment tree from given array
  101.     int *st = constructST(arr, n);
  102.  
  103.     // Print sum of values in array from index 1 to 3
  104.     printf("Sum of values in given range = %d\n", getSum(st, n, 1, 3));
  105.  
  106.     // Update: set arr[1] = 10 and update corresponding segment
  107.     // tree nodes
  108.     updateValue(arr, st, n, 1, 10);
  109.  
  110.     // Find sum after the value is updated
  111.     printf("Updated sum of values in given range = %d\n", getSum(st, n, 1, 3));
  112.  
  113.     return 0;
  114. }

Output:

$ gcc SegmentTree.c
$ ./a.out
 
Sum of values in given range = 15
Updated sum of values in given range = 22

Sanfoundry Global Education & Learning Series – 1000 C Programs.

Here’s the list of Best Books in C Programming, Data Structures and Algorithms.

If you find any mistake above, kindly email to [email protected]

advertisement
advertisement
Subscribe to our Newsletters (Subject-wise). Participate in the Sanfoundry Certification contest to get free Certificate of Merit. Join our social networks below and stay updated with latest contests, videos, internships and jobs!

Youtube | Telegram | LinkedIn | Instagram | Facebook | Twitter | Pinterest
Manish Bhojasia - Founder & CTO at Sanfoundry
Manish Bhojasia, a technology veteran with 20+ years @ Cisco & Wipro, is Founder and CTO at Sanfoundry. He lives in Bangalore, and focuses on development of Linux Kernel, SAN Technologies, Advanced C, Data Structures & Alogrithms. Stay connected with him at LinkedIn.

Subscribe to his free Masterclasses at Youtube & discussions at Telegram SanfoundryClasses.