难以理解构建分段树的递归

时间:2019-10-14 06:13:42

标签: c# segment-tree

假设存在一个带有n = 5的数组

int [] arr = {1,2,3,4,5};

int [] segmentTree = new int[n*4];

这是构建此segmentTree的代码

buildSegmentTree(a , 1 , 0 , n-1);

void buildSegmentTree(int [] a  , int vertex , int leftLimit , int rightLimit)
{    
     if(leftLimit == rightLimit)
     segmentTree[vertex] = a[leftLimit];
     else
     {
          int mid = (leftLimit + rightLimit)/2;
          //Builds the left part of the Segment Tree
          buildSegmentTree(a , vertex * 2 , leftLimit , mid);
          //Builds the right part of the Segment Tree
          buildSegmentTree(a , vertex*2 + 1 , mid+1 , rightLimit);
          segmentTree[vertex] = segmentTree[vertex*2] + segmentTree[vertex*2 + 1];
     }
}

当我打印细分树的值时,这就是我得到的输出

0 15 6 9 3 3 4 5 1 2 0 0 0 0 0 0 0 0 0 0

我了解这些值的含义(例如15是6和9的总和),但是我不了解如何存储它们以及如何执行调用。

1 个答案:

答案 0 :(得分:0)

通过在纸上构建树,您可以轻松理解它。
请紧记:
如果节点的间隔为(0,n-1),则左子节点为(0,mid-1),右子节点为(mid + 1,n-1)。

根据数组给定 arr ,采用间隔(0,4),因为它是您拥有的第一个节点。现在,通过找到该间隔的中间位置,我们得到了两个孩子:左边一个是(0,2),另一个是(3,4)。现在如下图所示:
(0,4)
/
(0,2)(3,4)
现在类似地,也拆分左孩子和右孩子,直到我们得到 leftLimit = rightLimit ,这样最终的树看起来就像:
(0,4)
/
(0,2)(3,4)
/ /
(0,1)(2,2)(3,3)(4,4)
/
(0,0)(1,1)

arr的第0个元素和第1个元素的和,即 1和2 以间隔(0,1),和的形式存储在节点中(0,1)和(2,2)存储在(0,2)中,依此类推。

通过这种方式,树将与包含整个数组 arr 的和的根元素一起构建。有关更多详细信息,请通过链接
https://www.hackerearth.com/practice/data-structures/advanced-data-structures/segment-trees/tutorial/
希望这会有意义并且会有所帮助:)