Binary Indexed Tree or Fenwick Tree in C++?

C++Server Side ProgrammingProgramming

In case of comparing with a flat array of numbers, the Fenwick tree results a much better balance between two operations: element update and prefix sum computation. In case of a flat array of m numbers, we can either store the elements, or the prefix sums. In case of first instance, calculating prefix sums needs linear time; in case of second instance, modifying or updating the array elements needs linear time (in both instances, the other operation can be accomplished in constant time). Fenwick trees permit both operations to be accomplished in O(log m) time. This is obtained by representing the numbers as a tree, where the value of each node is treated as the sum of the numbers in that subtree. The tree structure permits operations to be accomplished using only O(log m) node accesses.

By considering a one-based array, a Fenwick tree is most easily understood. Each element whose index j is a power of 2 contains the sum of the first j elements. Elements whose indices indicate the sum of two (distinct) powers of 2 consist of the sum of the elements since the preceding power of 2. Basically, each element consists of the sum of the values since its parent in the tree, and that parent is found by clearing the minimum or least-significant bit in the index.

To calculate the sum up to any given position or index, consider the binary expansion of the position or index, and add elements which correspond to each 1 bit in the binary form.

For example, let one wishes to calculate the sum of the first eleven values. Eleven is 1011 in binary. This consists of three 1 bits, so three elements must be added: 1000, 1010, and 1011. These consist of the sums of values 1-8, 9-10, and 11, respectively.

A simple C implementation follows.

Example

#define LSB(i) ((i) & -(i)) // zeroes all the bits except the minimum or least significant one
int A1[SIZE];
int sum(int i) // Returns the sum from index 1 to i{
   int sum = 0;
   while (i > 0)
   sum += A1[i], i -= LSB(i);
   return sum;
}
void add(int i, int k) // Adds k to element with index i{
   while (i < SIZE)
   A1[i] += k, i += LSB(i);
}

raja
Published on 29-Jan-2020 15:41:23
Advertisements