-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathMinimumSegmentTreeByArray.java
More file actions
89 lines (77 loc) · 3.02 KB
/
MinimumSegmentTreeByArray.java
File metadata and controls
89 lines (77 loc) · 3.02 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
public class MinimumSegmentTreeByArray extends SegmentTreeByArray {
/**
* Constructor for creating a Segment Tree from an input array
* @param arr Input array for which Segment Tree needs to be constructed
*/
public MinimumSegmentTreeByArray(int[] arr){
super(arr);
}
/**
* Recursivly builds the tree in this.tree .
* Saves min value in each node (this.tree[treeIdx]).
*
* @param arr the input array
* @param start The start index of the segment
* @param end The end index of the segment
* @param treeIdx The tree index in the this.tree array.
* @return Return used in the recursive action of this function. Returns the value of the node in treeIdx
*/
@Override
protected int rec_tree_build(int[] arr, int start, int end, int treeIdx) {
int left;
int right;
if (start == end) {
this.tree[treeIdx] = arr[start];
return arr[start];
}
int mid = getMidpoint(start, end);
left = rec_tree_build(arr, start, mid, treeIdx*2 + 1);
right = rec_tree_build(arr, mid+1, end, treeIdx*2 + 2);
this.tree[treeIdx] = Math.min(left,right);
return this.tree[treeIdx];
}
/**
* Helper function used to update the node based on the min value of its children
*
* @param nodeIdx Index of a node in the tree
*/
@Override
protected void updateNode(int nodeIdx) {
if ((nodeIdx*2 + 1 > this.tree.length - 1)) {
return; // index out of tree
}
if (this.tree[nodeIdx*2 + 1] == Integer.MIN_VALUE && this.tree[nodeIdx*2 + 2] == Integer.MIN_VALUE) {
return; // tries to update a node that has node child nodes but the array has allocated space in their spots
}
this.tree[nodeIdx] = Math.min(this.tree[nodeIdx*2 + 1], this.tree[nodeIdx*2 + 2]);
}
/**
* Queries the Segment Tree for the minimum value.
* @param node the current node
* @param start the start index
* @param end the end index
* @param left the left index
* @param right the right index
* @return the result of the query operation
*/
@Override
protected int query(int node, int start, int end, int left, int right) {
int leftNode;
int rightNode;
int newNode;
if ((start >= left) && (end <= right)) {
return this.tree[node];
}
int mid = getMidpoint(start, end);
if (right <= mid) {
newNode = query(node*2 + 1, start, mid, left, right); // go left
} else if (left > mid) {
newNode = query(node*2 + 2, mid+1, end, left, right); // go right
} else { // part left part right
leftNode = query(node*2 + 1, start, mid, left, right);
rightNode = query(node*2 + 2, mid+1, end, left, right);
newNode = Math.min(leftNode,rightNode);
}
return newNode;
}
}