Java 中的 Fenwick 树2025 年 5 月 13 日 | 阅读 6 分钟 在本节中,我们将学习 Java 中的 Fenwick 树。Fenwick 树也称为二叉索引树(BIT)。 使用 Fenwick 树的场景让我们了解一下在何种场景下会用到线段树。 假设我们有一个数组 a[] = {0, 1, …, s - 1},并希望对给定数组执行以下两个任务:
为了找到上述两个任务的解决方案,我们可以使用线段树或 Fenwick 树。线段树提供优化的解决方案。与线段树类似,Fenwick 树也可以使用数组表示。Fenwick 树的好处是易于编码,并且比线段树占用的空间更少。 注意:建议先阅读 Java 中的线段树主题,以便更好地理解 Fenwick 树。使用数组表示 Fenwick 树如上所述,Fenwick 树使用数组表示。令 fenArr[] 数组表示 Fenwick 树。Fenwick 树中的每一个节点都包含输入数组中某些元素的和。Fenwick 树的大小与输入数组的大小(在本例中为 s)相同。 使用数组构建 Fenwick 树首先,我们为 fenArr[] 数组分配内存,然后将该数组初始化为 0。之后,我们就可以在该数组上执行各种操作。 Fenwick 树上的操作计算给定输入数组 a[] 的子数组的和:要计算子数组元素的和,我们实现 getArrSum(y) 方法。 getArrSum(y):使用由输入数组 a[0, …, n] 构建的 fenArr[] 返回子数组 ar[0, …, y] 的和。 步骤 1:将结果总和初始化为 0,当前索引初始化为 y + 1。 步骤 2:重复步骤 a 和 b,直到当前索引大于 0。
步骤 3:返回总和。 ![]() 更新特定索引处的值:要实现特定索引处的更新,我们实现 **updateFenwick()** 方法。请注意,更新特定索引处的值不会对输入数组 a[] 产生任何影响。它只会对 fenArr[] 数组产生影响。 updateFenwick(y, v):该方法将索引 y 处的值更新为值 u。 步骤 1:将 y + 1 赋值给当前索引。 步骤 2:重复步骤 a 和 b,直到当前索引等于或小于 s。
![]() Fenwick 树的工作原理我们知道任何正数都可以表示为 2 的幂之和,这个思想已被用于 Fenwick 树。例如,21 可以写成 24 + 22 + 20 = 16 + 4 + 1。Fenwick 树的每个节点都包含 p 个元素的和,其中 p 是 2 的幂。考虑上面的图(getArrSum() 操作的图),前 12 个元素的总和可以通过将最后 4 个元素(从 9 到 12)相加,再加上前 8 个元素(从 1 到 8)的总和来实现。在二进制表示中,数字 n 的设置位数最多为 O(log(n))。因此,在 getArrSum() 和 updateFenwick() 操作中,都需要遍历最多 O(log(n)) 个节点。因此,由于对所有 n 个元素都调用了 updateFenwick() 操作,构建的时间复杂度为 O(n * log(n))。 Fenwick 树的实现让我们来实现 Fenwick 树以及上面定义的操作。 文件名: FenwickTreeExample.java 输出 Sum of the elements in array a[0 ... 6] is: 161 Sum of the elements in array a[0 ... 6] after update is: 168 |
悬空 else 问题是语言解释的歧义。在编程中,我们可以用以下两种形式编写条件执行的代码:if-then 形式 if-then-else 形式当我们处理嵌套的 if-else 语句时,该问题很少发生。这是一个歧义,不清楚...
阅读 2 分钟
在 Java 中查找具有不同元素的数组的交集涉及识别两个或多个数组共有的公共元素。由于每个数组中的元素都是唯一的,因此任务简化为有效地比较集合。此过程在数据过滤、集合...等各种应用程序中很有用。
阅读 8 分钟
将一种类型的对象和变量转换为另一种类型的过程称为类型转换。当编译器在程序员的干预下自动执行转换时,称为隐式类型转换或自动类型提升。在隐式类型转换中,转换涉及较小的...
阅读 3 分钟
Groovy 和 Java 的区别 Groovy 是一种可选类型和动态编程语言,用于在 Java 平台上开发应用程序。Groovy 的语法与 Java 相似。Groovy 是一种非常强大、强类型、动态和静态的编程语言,它扩展了 JDK。通过扩展...
阅读 3 分钟
Java 程序可以使用简单的文本编辑器编写。但是,使用 Java 集成开发环境 (IDE) 可以帮助开发人员更有效地开发软件。IDE 提供了许多功能,如自动完成、调试器选项等。在本节中,我们将讨论一些广泛使用的 Java...
阅读 3 分钟
在本节中,我们将学习如何通过 Java 程序交换矩阵的对角线。这通常在 Java 面试和学术中被问到。考虑上面大小为 n 的 4*4 矩阵。在上面的矩阵中,我们需要交换以下索引才能交换...
阅读 4 分钟
? Java Final 方法 final 关键字在 Java 中可用于禁止方法重写、声明常量和阻止继承。标记为 final 的方法表示不允许子类重写它。在许多情况下,它可能非常有用,...
阅读 3 分钟
索引映射,也称为平凡哈希,是一种将数组元素映射到新数组中索引的技术。这可用于有效地执行查找重复项或计算数组中元素出现次数等操作。一种常见的实现……
阅读 10 分钟
线程是正在执行的程序,用于执行特定任务。Java 线程的生命周期从其诞生开始,到其消亡结束。Thread 类的 start() 方法用于启动线程的执行,它会……
5 分钟阅读
在数论领域,Kaprekar 数因其有趣的性质而占有特殊地位。这些数字以印度数学家 D. R. Kaprekar 的名字命名,它们具有一个独特的特性,即可以将它们分成两部分,这两部分的平方相加可以得到...
5 分钟阅读
我们请求您订阅我们的新闻通讯以获取最新更新。
我们提供所有技术(如 Java 教程、Android、Java 框架)的教程和面试问题
G-13, 2nd Floor, Sec-3, Noida, UP, 201301, India