Skip to content

algorithm: SegmentTree #1178

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
Oct 20, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
97 changes: 97 additions & 0 deletions Data-Structures/Tree/SegmentTree.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
/**
* Segment Tree
* concept : [Wikipedia](https://en.wikipedia.org/wiki/Segment_tree)
* inspired by : https://www.geeksforgeeks.org/segment-tree-efficient-implementation/
*
* time complexity
* - init : O(N)
* - update : O(log(N))
* - query : O(log(N))
*
* space complexity : O(N)
*/
class SegmentTree {
size
tree
constructor (arr) {
// we define tree like this
// tree[1] : root node of tree
// tree[i] : i'th node
// tree[i * 2] : i'th left child
// tree[i * 2 + 1] : i'th right child
// and we use bit, shift operation for index
this.size = arr.length
this.tree = new Array(2 * arr.length)
this.tree.fill(0)

this.build(arr)
}

// function to build the tree
build (arr) {
const { size, tree } = this
// insert leaf nodes in tree
// leaf nodes will start from index N
// in this array and will go up to index (2 * N – 1)
for (let i = 0; i < size; i++) {
tree[size + i] = arr[i]
}

// build the tree by calculating parents
// tree's root node will contain all leaf node's sum
for (let i = size - 1; i > 0; --i) {
// current node's value is the sum of left child, right child
tree[i] = tree[i * 2] + tree[i * 2 + 1]
}
}

update (index, value) {
const { size, tree } = this

// only update values in the parents of the given node being changed.
// to get the parent move to parent node (index / 2)

// set value at position index
index += size
// tree[index] is leaf node and index's value of array
tree[index] = value

// move upward and update parents
for (let i = index; i > 1; i >>= 1) {
// i ^ 1 turns (2 * i) to (2 * i + 1)
// i ^ 1 is second child
tree[i >> 1] = tree[i] + tree[i ^ 1]
}
}

// interval [L,R) with left index(L) included and right (R) excluded.
query (left, right) {
const { size, tree } = this
// cause R is excluded, increase right for convenient
right++
let res = 0

// loop to find the sum in the range
for (left += size, right += size; left < right; left >>= 1, right >>= 1) {
// L is the left border of an query interval

// if L is odd it means that it is the right child of its parent and our interval includes only L and not the parent.
// So we will simply include this node to sum and move to the parent of its next node by doing L = (L + 1) / 2.

// if L is even it is the left child of its parent
// and the interval includes its parent also unless the right borders interfere.
if ((left & 1) > 0) {
res += tree[left++]
}

// same in R (the right border of an query interval)
if ((right & 1) > 0) {
res += tree[--right]
}
}

return res
}
}

export { SegmentTree }
16 changes: 16 additions & 0 deletions Data-Structures/Tree/test/SegmentTree.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { SegmentTree } from '../SegmentTree'

describe('SegmentTree sum test', () => {
const a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]

const segment = new SegmentTree(a)

it('init sum check', () => {
expect(segment.query(0, 2)).toBe(6)
})

it('init sum check', () => {
segment.update(2, 1)
expect(segment.query(0, 2)).toBe(4)
})
})
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy