Skip to content

Commit a36b931

Browse files
authored
Merge pull request #177 from RishabhBhatnagar/master
Add Segment Tree Data Structure
2 parents 14aea11 + 92ef83c commit a36b931

File tree

1 file changed

+103
-0
lines changed

1 file changed

+103
-0
lines changed

Data_Structure/src/segment_tree.py

+103
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
'''
2+
Segment Tree is used for storing information about intervals, or segments.
3+
It allows querying which of the stored segments contain a given point.
4+
5+
A segment tree for a set I of n intervals uses O(n log n) storage and can be built in O(n log n) time.
6+
Segment trees support searching for all the intervals that contain a query point in O(log n + k),
7+
k being the number of retrieved intervals or segments.
8+
\cite{https://en.m.wikipedia.org/wiki/Segment_tree }
9+
'''
10+
11+
12+
from typing import TypeVar, List, Callable
13+
from functools import reduce
14+
15+
16+
T = TypeVar('T') # Basic Template allowing any variable as input.
17+
18+
19+
def build(arr: List[T], n: int, func: Callable[[T, T], T]) -> List[T]:
20+
"""
21+
builds the trees from the passed list.
22+
Time Complexity: O(n)
23+
24+
Parameters
25+
----------
26+
arr: iterable
27+
list of elements to be added to the data structure
28+
func: Callable
29+
function that will be binary operator
30+
31+
Returns
32+
-------
33+
Built Segment Tree
34+
"""
35+
tree = [0 for i in range(n)]
36+
tree.extend(arr)
37+
for i in range(n-1, 0, -1):
38+
tree[i] = func(tree[i << 1], tree[i << 1 | 1])
39+
return tree
40+
41+
42+
def point_update(tree: List[T], n: int, pos: int, val: int, func: Callable[[T, T], T]) -> None:
43+
"""
44+
Updates the tree with given value.
45+
Time Complexity: O(lgn)
46+
47+
Parameters
48+
----------
49+
tree: list
50+
built segment tree
51+
n: int
52+
size of segment tree
53+
pos: int
54+
index which is to be updated.
55+
val: int
56+
the value with which arr[pos] is to be updated.
57+
func: Callable
58+
binary operator which will be applied to the input parameters.
59+
"""
60+
pos += n
61+
tree[pos] = val
62+
while pos > 1:
63+
tree[pos >> 1] = func(tree[pos], tree[pos ^ 1])
64+
pos >>= 1
65+
66+
67+
def query(tree: List[T], l: int, r: int, n: int, func: Callable[[T, T], T], start_ans=0, right_inclusive=True):
68+
"""
69+
Parameters
70+
----------
71+
tree: segment Tree
72+
l: left
73+
r: right
74+
n: max size of array
75+
func: Callable to be operated on the input parameters.
76+
start_ans: seed value with which run is to be initialised
77+
"""
78+
79+
l += n
80+
r += n + right_inclusive
81+
ans = start_ans
82+
while l < r:
83+
if l & 1:
84+
ans = func(ans, tree[l])
85+
l += 1
86+
if r & 1:
87+
r -= 1
88+
ans = func(ans, tree[r])
89+
l >>= 1
90+
r >>= 1
91+
return ans
92+
93+
94+
95+
if __name__ == '__main__':
96+
arr = [3, 2, 4, 5, 6, 8, 2, 4, 5]
97+
n = len(arr)
98+
func = int.__mul__
99+
tree = build(arr, n, func)
100+
point_update(tree, n, 0, 0, func)
101+
l, r = 2, 4
102+
assert query(tree, l, r, n, func, start_ans=1) == reduce(func, arr[l: r+1]), "Segment Tree faulty"
103+

0 commit comments

Comments
 (0)