设计小型可比对象

时间:2010-06-06 18:32:34

标签: algorithm memory comparison numbers

简介

考虑您有一个键/值对列表:

(0,a) (1,b) (2,c)

你有一个函数,它在两个当前对之间插入一个新值,你需要给它一个保持顺序的键:

(0,a) (0.5,z) (1,b) (2,c)

这里选择新密钥作为边界对的平均密钥之间的平均值。

问题是,你列出的可能有数百万个插入。如果这些插入都彼此靠近,你可能会得到2^(-1000000)这样的密钥,这些密钥在任何标准或特殊编号类中都不容易存储。

问题

如何设计生成密钥的系统:

  • 与其他所有键相比,给出正确的结果(大于/小于)。
  • 仅占用O(logn)个内存(其中n是列表中的项目数)。

我的尝试

  • 首先我尝试了不同的数字类。像分数甚至多项式一样,但我总能找到密钥大小与插入数量呈线性增长的例子。
  • 然后我想到保存指向其他一些键的指针,并保存较低/大于关系,但这总是需要至少O(sqrt)内存和时间进行比较。

额外信息:理想情况下,当从列表中删除对时,算法不应该中断。

2 个答案:

答案 0 :(得分:2)

我同意雪人。在这种情况下,树将是理想的。红黑树会阻止事物变得不平衡。但是,如果你真的需要键,我很确定你不能比使用你需要插入的值两侧的平均键做得更好。这会使你的密钥长度每次增加1位。我建议定期重新规范密钥。每次x插入,或者当您检测到生成的密钥太近时,重新编号从1到n的所有内容。

修改 如果您按位置而不是键插入,则无需比较键。红黑树的比较函数只使用概念列表中的顺序,该顺序在树中按顺序排列。如果要在列表中插入位置4,请在树中的位置4处插入一个节点(使用按顺序排列)。如果您在某个节点(例如“a”)之后插入,则它是相同的。如果您使用的语言/库需要密钥,则可能必须使用自己的实现。

答案 1 :(得分:1)

我不认为你可以避免在没有重新分配密钥的情况下获得大小的O(n)密钥。

作为一个实用的解决方案,我会构建一个倒置的搜索树,其中包含从子节点到父节点的指针,其中每个指针都标记为来自左子节点还是右子节点。要比较两个元素,你需要找到最接近的共同祖先,其中元素的路径发散。

重新分配密钥然后重新平衡树,你可以通过一些不改变顺序的轮换来做到这一点。