![]() |
1
3
我把你的问题理解为: 每个bucket都有一个内部顺序,bucket本身也有一个顺序,所以所有的元素都有一些顺序,您需要该顺序中的第i个元素。
您可以做的是维护一个“累积值”树,其中叶节点(x1,x2,…,xn)是bucket的大小。节点的值是其直接子节点的值之和。保持n的幂为2将使它变得简单(你可以在最后用零大小的桶填充它),树将是一个完整的树。
例如,假设桶的尺寸是2,1,4,8。 这棵树看起来像
如果需要总计数,请读取根节点的值。
例如,如果您将4个项目添加到第二个bucket中,它将是(标有*的节点是更改的节点)
如果你想找到第i个元素,你可以沿着上面的树走,有效地进行二进制搜索。你已经有了左子和右子计数。如果i>当前节点的左子节点值,减去左子节点值并在右树中递归。如果i<=左子节点值,则向左移动并再次递归。
因为根的左子级是7<9 你从9中减去7(得到2),然后右转。 自2<4(12岁的左孩子),你向左走。 您位于与第三个bucket对应的叶节点。现在您需要在该桶中选择第二个元素。
得到的总计数是O(1)。 更新单个bucket/查找项目are O(logn)。 增加新桶按O(1)摊销。
代替二叉树,你也可以用B树做同样的事情。 |
![]() |
2
0
芬威克树 我们只剩下两种数据结构:二叉索引树(讽刺的是,芬威克用这个名字来描述他的结构)和排序跳过列表。
我倾向于跳过列表而不是二叉树,因为它们是自组织的,所以我省去了不断重新平衡我的树的麻烦。
这些结构将允许到达第i个元素
另一个有趣的实现细节是 我有一个指向此元素的指针,但其他元素可能已被插入/删除,我现在如何知道我的元素的排名? 如果bucket指向拥有它的节点,这是可能的。但这意味着要么节点不应该移动,要么它应该在移动时更新bucket的指针。 |
![]() |
magic_al · MySQL索引的B树节点中有多少个条目? 7 年前 |