A célunk egy olyan bináris fa létrehozása, amelynek levelei a tömb elemeit tárolják, a belső csomópontok pedig bizonyos intervallumok eredményeit (pl. összegeket) tartalmazzák.
[36] / \ [9] [27] / \ / \ [4] [5] [16] [11] / \ / \ [1] [3] [7] [9]
build(start, end, parent) {
if (start === end) {
return new Node(parent, this.numbers[start], [start, end], null);
}
let mid = Math.floor((start + end) / 2);
let leftChild = this.build(start, mid, null);
let rightChild = this.build(mid + 1, end, null);
let value = leftChild.value + rightChild.value;
let node = new Node(parent, value, [start, end], [leftChild, rightChild]);
leftChild.parent = node;
rightChild.parent = node;
return node;
}
Vesszővel elválasztva add meg az értékeket! Pl.: 9,15,12,68,91
A szegmensfa egyik legnagyobb előnye, hogy gyorsan tudunk intervallum lekérdezéseket végrehajtani. Például egy adott tartomány összegét kérdezhetjük le.
query(node, L, R) {
if (!node || node.interval[1] < L || node.interval[0] > R) {
return 0;
}
if (L <= node.interval[0] && node.interval[1] <= R) {
return node.value;
}
let leftSum = this.query(node.children[0], L, R);
let rightSum = this.query(node.children[1], L, R);
return leftSum + rightSum;
}
Ezzel a módszerrel gyorsan, O(log N)
idő alatt végezhetünk intervallum
lekérdezéseket.
Vesszővel elválasztva add meg az értékeket! Pl.: 9,15,12,68,91
A szegmensfa segítségével gyorsan frissíthetünk egy adott indexű elemet, és az érintett csomópontok újra kiszámításra kerülnek.
update(index, newValue) {
// Kezdőpont a gyökér csomópont
let node = this.root;
// Rekurzívan keressük meg a levelet, amely tartalmazza az indexet
while (node.interval[0] !== node.interval[1]) {
let mid = Math.floor((node.interval[0] + node.interval[1]) / 2);
if (index <= mid) {
node = node.children[0];
} else {
node = node.children[1];
}
}
// Frissítjük a levelet az új értékre
let difference = newValue - node.value;
node.value = newValue;
// Visszafelé haladva frissítjük az ősök értékeit is
let parent = node.parent;
while (parent !== null) {
parent.value += difference;
parent = parent.parent;
}
}
Az update művelet is O(log N)
időben fut, mivel csak egy útvonalon kell frissíteni
az
értékeket.
Vesszővel elválasztva add meg az értékeket! Pl.: 9,15,12,68,91