|
1 |
| -// NOTE: This file is a current WIP! |
2 |
| -// |
3 |
| -// Run with: |
4 |
| -// ./gradlew run -Palgorithm=datastructures.segmenttree.RangeQueryPointUpdateSegmentTree |
5 |
| -// |
6 |
| -// Several thanks to cp-algorithms for their great article on segment trees: |
7 |
| -// https://cp-algorithms.com/data_structures/segment_tree.html |
8 |
| - |
| 1 | +/** |
| 2 | + * Simple segment tree implementation that supports sum range queries and point updates. |
| 3 | + * |
| 4 | + * <p>NOTE: This file is still a little bit of a WIP |
| 5 | + * |
| 6 | + * <p>Run with: ./gradlew run |
| 7 | + * -Palgorithm=datastructures.segmenttree.RangeQueryPointUpdateSegmentTree |
| 8 | + * |
| 9 | + * <p>Several thanks to cp-algorithms for their great article on segment trees: |
| 10 | + * https://cp-algorithms.com/data_structures/segment_tree.html |
| 11 | + * |
| 12 | + * @author William Fiset, william.alexandre.fiset@gmail.com |
| 13 | + */ |
9 | 14 | package com.williamfiset.algorithms.datastructures.segmenttree;
|
10 | 15 |
|
11 | 16 | public class RangeQueryPointUpdateSegmentTree {
|
@@ -47,21 +52,19 @@ public RangeQueryPointUpdateSegmentTree(int[] values) {
|
47 | 52 | * @param values the initial values array
|
48 | 53 | * <p>The range [l, r] over the values array is inclusive.
|
49 | 54 | */
|
50 |
| - private int buildTree(int i, int tl, int tr, int[] values) { |
| 55 | + private void buildTree(int i, int tl, int tr, int[] values) { |
51 | 56 | if (tl == tr) {
|
52 |
| - return t[i] = values[tl]; |
| 57 | + t[i] = values[tl]; |
| 58 | + return; |
53 | 59 | }
|
54 | 60 | int mid = (tl + tr) / 2;
|
55 | 61 |
|
56 |
| - // TODO(william): fix segment index out of bounds issue |
57 |
| - // System.out.printf("Range [%d, %d] splits into: [%d, %d] and [%d, %d] | %d -> %d and %d\n", l, |
58 |
| - // r, l, mid, mid+1, r, i, tl, tr); |
59 |
| - int lSum = buildTree(2 * i + 1, tl, mid, values); |
60 |
| - int rSum = buildTree(2 * i + 2, mid + 1, tr, values); |
| 62 | + buildTree(2 * i + 1, tl, mid, values); |
| 63 | + buildTree(2 * i + 2, mid + 1, tr, values); |
61 | 64 |
|
62 | 65 | // TODO(william): Make generic to support min, max and other queries. One idea is to keep
|
63 | 66 | // segment multiple trees for each query type?
|
64 |
| - return t[i] = lSum + rSum; |
| 67 | + t[i] = t[2 * i + 1] + t[2 * i + 2]; |
65 | 68 | }
|
66 | 69 |
|
67 | 70 | /**
|
@@ -155,11 +158,11 @@ public static void main(String[] args) {
|
155 | 158 | int[] values = new int[6];
|
156 | 159 | java.util.Arrays.fill(values, 1);
|
157 | 160 | RangeQueryPointUpdateSegmentTree st = new RangeQueryPointUpdateSegmentTree(values);
|
158 |
| - System.out.println(st.sumQuery(1, 4)); |
| 161 | + System.out.println(st.sumQuery(1, 4)); // 4 |
159 | 162 |
|
160 | 163 | st.update(1, 2);
|
161 |
| - System.out.println(st.sumQuery(1, 1)); |
162 |
| - System.out.println(st.sumQuery(0, 1)); |
163 |
| - System.out.println(st.sumQuery(0, 2)); |
| 164 | + System.out.println(st.sumQuery(1, 1)); // 2 |
| 165 | + System.out.println(st.sumQuery(0, 1)); // 3 |
| 166 | + System.out.println(st.sumQuery(0, 2)); // 4 |
164 | 167 | }
|
165 | 168 | }
|
0 commit comments