Skip to content

Commit

Permalink
Added fenwick tree class
Browse files Browse the repository at this point in the history
  • Loading branch information
spirosmaggioros committed Oct 19, 2024
1 parent 96078e9 commit e5b633f
Show file tree
Hide file tree
Showing 3 changed files with 125 additions and 0 deletions.
63 changes: 63 additions & 0 deletions src/classes/tree/fenwick_tree.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
#ifndef FENWICK_TREE_H
#define FENWICK_TREE_H

#ifdef __cplusplus
#include <iostream>
#include <vector>
#endif

/**
* @brief fenwick tree class
*/
template <typename T>
struct fenwick_tree {
std::vector<T> tree;
int n;

/**
* @brief default constructor of fenwick tree class
* @param v: the input vector
*/
explicit fenwick_tree(const std::vector<T> &v) noexcept : n(int(v.size())) {
tree = std::vector<T>(n, 0);
for(int i = 0; i<n; i++) {
this->update(i, v[i]);
}
}

/**
* @brief sum query function
* @param k: the ending index of the query
* @return T: the sum of range [0, k]
*/
T sum(int k) {
T sum = 0;
for(; k >= 0; k = (k & (k + 1)) - 1) {
sum += tree[k];
}
return sum;
}

/**
* @brief sum query function(from index a to b)
* @param a: starting index
* @param b: ending index
* @returns T: the sum of range [a, b]
*/
T sum(int a, int b) {
return sum(b) - sum(a - 1);
}

/**
* @brief update query function
* @param k: the index
* @param x: the value that will be added to data[k]
*/
void update(int k, int x) {
for(; k < n; k = k | (k + 1)) {
tree[k] += x;
}
}
};

#endif
37 changes: 37 additions & 0 deletions tests/tree/fenwick_tree.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
#include "../../src/classes/tree/fenwick_tree.h"
#include "../../third_party/catch.hpp"


TEST_CASE("Testing fenwick tree default constructor") {
std::vector<int> v = {1, 4, 5, 6, 7};
CHECK_NOTHROW(fenwick_tree<int>(v));
}

TEST_CASE("Testing fenwick tree sum query [1]") {
std::vector<int> v = {1, 2, 3, 4, 5};
fenwick_tree<int> f(v);
REQUIRE(f.sum(2) == 6);
REQUIRE(f.sum(1) == 3);
REQUIRE(f.sum(4) == 15);
REQUIRE(f.sum(0) == 1);
}

TEST_CASE("Testing fenwick tree sum query [2]") {
std::vector<int> v = {1, 2, 3, 4, 5};
fenwick_tree<int> f(v);
REQUIRE(f.sum(2) == 6);
REQUIRE(f.sum(4) == 15);
REQUIRE(f.sum(1, 2) == 5);
REQUIRE(f.sum(3, 4) == 9);
REQUIRE(f.sum(1, 3) == 9);
}

TEST_CASE("Testing update query [1]") {
std::vector<int> v = {1, 2, 3, 4, 5};
fenwick_tree<int> f(v);

f.update(0, 2);
REQUIRE(f.sum(0, 1) == 5);
f.update(0, -5);
REQUIRE(f.sum(0, 2) == 3);
}
25 changes: 25 additions & 0 deletions tutorial/tree/fenwick_tree.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
### Mini tutorial for fenwick tree class

-- fenwick_tree<T> creates a fenwick tree with nodes of type T

### *default constructor*:
```cpp
vector<int> v = {1, 2, 3, 4, 5};
fenwick_tree<int> f(v); // this creates the fenwick tree
// with the passed vector v
```
### *sum query*:
```cpp
...
cout << f.sum(2) << '\n'; // this should return 6
cout << f.sum(0, 2) << '\n'; // this should return 6 as well
```

### *update query*:
```cpp
...
f.update(0, -5); // updates the value of index 0 to -4(1 + -5)
cout << f.sum(2) << '\n'; // this should return 1 now
cout << f.sum(0, 2) << '\n'; // this should return 1 as well
```

0 comments on commit e5b633f

Please sign in to comment.