简介
考虑您有一个键/值对列表:
(0,a) (1,b) (2,c)
你有一个函数,它在两个当前对之间插入一个新值,你需要给它一个保持顺序的键:
(0,a) (0.5,z) (1,b) (2,c)
这里选择新密钥作为边界对的平均密钥之间的平均值。
问题是,你列出的可能有数百万个插入。如果这些插入都彼此靠近,你可能会得到2^(-1000000)
这样的密钥,这些密钥在任何标准或特殊编号类中都不容易存储。
问题
如何设计生成密钥的系统:
O(logn)
个内存(其中n是列表中的项目数)。我的尝试
O(sqrt)
内存和时间进行比较。额外信息:理想情况下,当从列表中删除对时,算法不应该中断。
答案 0 :(得分:2)
我同意雪人。在这种情况下,树将是理想的。红黑树会阻止事物变得不平衡。但是,如果你真的需要键,我很确定你不能比使用你需要插入的值两侧的平均键做得更好。这会使你的密钥长度每次增加1位。我建议定期重新规范密钥。每次x插入,或者当您检测到生成的密钥太近时,重新编号从1到n的所有内容。
修改强> 如果您按位置而不是键插入,则无需比较键。红黑树的比较函数只使用概念列表中的顺序,该顺序在树中按顺序排列。如果要在列表中插入位置4,请在树中的位置4处插入一个节点(使用按顺序排列)。如果您在某个节点(例如“a”)之后插入,则它是相同的。如果您使用的语言/库需要密钥,则可能必须使用自己的实现。
答案 1 :(得分:1)
我不认为你可以避免在没有重新分配密钥的情况下获得大小的O(n)密钥。
作为一个实用的解决方案,我会构建一个倒置的搜索树,其中包含从子节点到父节点的指针,其中每个指针都标记为来自左子节点还是右子节点。要比较两个元素,你需要找到最接近的共同祖先,其中元素的路径发散。
重新分配密钥然后重新平衡树,你可以通过一些不改变顺序的轮换来做到这一点。