其实关于线段树已经有很多博客的水平远远超过本文,而本文的目的只是在于给出线段树的建立,点修改,求和的不同的并且详细的写法,想给与作者一样的小白一点帮助
·什么是线段树
线段树是一种二叉搜索树,与区间树相似,它将一个区间划分成一些单元区间,每个单元区间对应线段树中的一个叶结点。
简单的来说线段树的作用是将一个区间划分为若干个子区间,它的每一个节点代表了一个子区间。线段树总是拥有这样的性质 :对于B>A的区间[A,B]总有其左子节点的区间为[A,(A+B)/2],其右子节点的的区间为[(A+B)/2+1,B]。
作为高级数据结构的一种,我们首先得了解我们使用线段树来干些什么:
1.数字之和——总数字之和 = 左区间数字之和 + 右区间数字之和
2. 最大公因数(GCD)——总GCD = gcd( 左区间GCD , 右区间GCD );
3.最大值——总最大值=max(左区间最大值,右区间最大值)
接下来是一些关于二叉树的原理图
引自 岩之痕 大佬 >https://blog.csdn.net/zearot/article/details/52280189
我们之所以使用线段树的原因,除了其固有的性质外还有很重要的一点在于我们可以用数组实现它,那我们如何用数组建立一个线段树呢?
这里是一个很详细的二叉堆实现过程,实际上的话二叉堆与线段树大同小异,所以将这个链接贴在这里,不明白基本定义可以看一下
skywang12345 大佬 http://www.cnblogs.com/skywang12345/p/3610187.html
几个需要注意的地方做一下笔记:
1.线段树开的是一维数组, 然后我们可以通过这样的计算得出我们应该释放的内存大小。
对于一个长度为N的区间(这里假设了N正好是2的一个n次幂),显然可以计算得到其层数为log2N+1,所以的话对于每一层其节点个数为2n-1,进行求和
∑ i =