插入键值对后在搜索树中增加值
Posted
技术标签:
【中文标题】插入键值对后在搜索树中增加值【英文标题】:Incrementing values in a search tree after insertion of a key-value pair 【发布时间】:2011-08-16 02:02:54 【问题描述】:我正在解决一个编程问题,但遇到了障碍。我正在尝试提出一种数据结构来将任意整数映射到另一个整数。您可能倾向于说“哈希表!”或“搜索树!”,实际上我已经想到了这些(甚至尝试了一个肮脏的实现)。但是,有一个问题!
每次我从映射中插入或删除一个值时,我还想增加/减少(通过一个或某个任意偏移量)所有大于或等于插入/删除值的值。
这是一个例子。
假设我有两个整数列表,我将用于此映射中的键和值:
Keys: (1, 6, 18, 21, 24)
Vals: (2, 1, 3, 0, 4)
现在,如果我添加一个键值对 (7, 1),我想增加所有大于或等于 1 的值,结果如下:
Keys: (1, 6, 7, 18, 21, 24)
Vals: (3, 2, 1, 4, 0, 5)
随后如果我删除键值对 (21, 0),结果如下:
Keys: (1, 6, 7, 18, 24)
Vals: (2, 1, 0, 3, 4)
这对于几个列表/数组和每次插入/删除后的一些处理(即遍历值并逐个更改它们)是相当微不足道的。
但是,我正在寻找一种更有效的方法,也许不必遍历整个值列表并增加/减少它们。甚至可以延迟递增/递减,直到请求了一个值(应该递增/递减)。
有什么想法吗?
【问题讨论】:
【参考方案1】:我认为如果你需要通过某个键进行快速查找,并根据实际值修改结果,你需要两种数据结构:一种用于键,一种用于值。
key 的数据结构将只是一个关联数组(将其实现为哈希表、自平衡树或跳过列表,没关系),从键到值的树中的节点.
值的树将是一个自平衡二叉搜索树(或跳过列表,请参阅下面的编辑)。树中的节点具有与它们关联的增量以及它们的值。增量适用于大于或等于特定节点的所有节点,即它适用于自身及其右子树中的所有节点。
当您插入一个值时,您会增加大于或等于您正在插入的值的所有节点的增量。这会增加值大于或等于您在整个树中插入的值的所有节点的实际值。删除类似,你只是用增量替换为减量。
当你想读取一个值时,你使用基于键的结构在基于值的树中找到节点。然后爬到根节点(为此,您必须保留指向树中节点父节点的指针)并从节点累积增量,其值大于或等于您开始的节点中的值。
根据您选择的自平衡算法要求进行重新平衡时必须小心,因为您必须重新计算某些节点的增量,但这不应该影响时间复杂度。
编辑: 对于跳过列表,管理增量非常容易:当您正在寻找插入位置时,在您比较的链表中的每个节点中增加增量或等于您插入的值(这也意味着您将下降一级)。删除是类似的,只是您必须将删除的项目保留的所有增量移动到右侧。
当您想计算某个节点的实际值时,在当前项目中尽可能爬高,在此处应用增量(一个项目可以在不同级别上多次插入或删除的增量,您总是有使用***别的值),然后进入链表左侧的一个节点并重复该过程,直到到达最左侧的项目。
您访问节点的方式也意味着链表必须是双向链接的。
【讨论】:
如何修改以支持跳过列表而不是平衡二叉树(因为平衡算法似乎需要复杂才能处理增量管理)? 我必须考虑一下(也许明天我会考虑)。但是在scapegoat tree 中应该很容易做到这一点:只需评估实际值并重置您当前正在重建的子树中的任何增量。 这听起来是个不错的解决方案。我要试试这个。感谢您的帮助!以上是关于插入键值对后在搜索树中增加值的主要内容,如果未能解决你的问题,请参考以下文章
使用带有 sql 的键值对搜索 php 多维关联数组,例如 '%LIKE%' 构造