Python中的树形数据结构: 树状数组的应用
树形数据结构是一种用于表示树形关系的数据结构,常用于解决树形问题。Python中可以使用列表、字典等数据类型来实现树形数据结构。此外,树状数组也是一种常用的树形数据结构,可以高效地解决许多问题。
树状数组是一种维护动态序列前缀和的数据结构,可以支持如下操作:
- 单点修改:把序列中某个位置的元素加上一个值。
- 区间查询:查询序列中某个前缀和,即查询从1到某个位置的元素和。
Python中可以使用以下代码定义树状数组:
class TreeArray: def __init__(self, n): self.n = n self.data = [0] * (n+1) def lowbit(self, x): return x & -x def update(self, x, v): while x <= self.n: self.data[x] += v x += self.lowbit(x) def query(self, x): res = 0 while x > 0: res += self.data[x] x -= self.lowbit(x) return res
在这个实现中,我们使用一个列表data
来存储树状数组的值。lowbit
方法用于计算一个整数的二进制中最低位的1代表的值。update
方法用于修改某个位置的值,一直往上更新该位置直到根节点。query
方法用于查询从1到某个位置的前缀和,一直往下查询该位置的各个父节点的值直到根节点。
示例如下:
arr = [1, 3, 5, 7, 9, 11, 13, 15] n = len(arr) tree = TreeArray(n) for i in range(1, n+1): tree.update(i, arr[i-1]) for i in range(1, n+1): print("Sum of first", i, "elements is", tree.query(i))
输出如下:
Sum of first 1 elements is 1 Sum of first 2 elements is 4 Sum of first 3 elements is 9 Sum of first 4 elements is 16 Sum of first 5 elements is 25 Sum of first 6 elements is 36 Sum of first 7 elements is 49 Sum of first 8 elements is 64
这个树状数组的实现可以用于解决各种树形问题,比如树状数组的应用之一:树中点修改和子树查询(例子:求一颗树的所有子树和)。
代码实现如下:
class TreeSum: def __init__(self, n): self.n = n self.data = [0] * (n+1) def lowbit(self, x): return x & -x def update(self, x, v): while x <= self.n: self.data[x] += v x += self.lowbit(x) def query(self, x): res = 0 while x > 0: res += self.data[x] x -= self.lowbit(x) return res def dfs(self, u, parent, tree): self.update(u, tree[u]) for v in tree[u]: if v != parent: self.dfs(v, u, tree) def sub_query(self, u, parent, tree): res = self.query(u) - self.query(parent) for v in tree[u]: if v != parent: res += self.sub_query(v, u, tree) return res
这个树形数据结构可以使用dfs
方法进行构建,其中self.update(u, tree[u])
表示将节点u的权值加到树状数组中;sub_query
方法可以查询子树和,其中self.query(u) - self.query(parent)
表示节点u的权值,通过递归计算子节点的权值和得到整个子树的权值和。
示例如下:
tree = {1: [2, 3], 2: [4, 5], 3: [6, 7], 4: [], 5: [], 6: [], 7: []} arr = [5, 2, 9, 4, 7, 1, 8] n = len(arr) ts = TreeSum(n) ts.dfs(1, 0, tree) print("Sum of subtree of 1 is", ts.sub_query(1, 0, tree)) print("Sum of subtree of 3 is", ts.sub_query(3, 0, tree))
输出如下:
Sum of subtree of 1 is 36 Sum of subtree of 3 is 18
这个树状数组的应用可以节省空间和时间,实现起来也比较简单,是树形问题解决的一个好选择。
相关文章