自然数的生成器,它返回已经返回但尚未释放的最小数字

时间:2016-02-10 01:02:08

标签: algorithm performance collections

我正在寻找以下任务的已知算法:

  1. 我需要一个对象X,它为我提供了两种方法:
    • take()返回未采用的最小自然数,即此方法的顺序调用将返回123等等。
    • free(n)标记n如果已经拍摄则不会拍摄,或者如果之后没有拍摄则会引发异常,或者在此之后被释放。
  2. 示例:

    take = 1
    take = 2
    take = 3
    free(2)
    take = 2
    take = 4
    free(3)
    free(2)
    free(1)
    take = 1
    take = 2
    take = 3
    take = 5
    free(6) : exception
    

    我发明了bit-set-b-tree(不确定如何正确调用它),其中leaves包含为所有捕获的数字设置的实际位,而其他节点则为了搜索目的而分组。每个非叶节点都有32个子节点,因此叶位集中每个位的内存开销是1/31位。

    实际搜索“洞”'在节点(叶子和非叶子)中完成基于位操作的二进制搜索,其执行log2(32) = 5操作,而从根到叶子的遍历节点需要log32(L)其中L是最后一个被采取的号码'状态。

    因此,两个操作都需要5*log32(L),并且需要大约1.032*L个位才能将该结构存储在内存中。在最坏的情况下,L不能同时大于最大数量。即使除了一个数字之外所有数字都被释放,它也不会减少,但如果此时从未超过10个数字,则L将小于或等于10。

    你怎么看待我重新发明轮子?

    我之所以需要这种结构是一个非常具体的id生成,但可能还有其他的应用?这是一个额外的问题:)

    感谢您的关注。

2 个答案:

答案 0 :(得分:0)

看起来很有效率。

每个非叶子节点平均少于32个孩子。 32对于叶子的二进制搜索时间是正确的最大值,但是可能在5 * log d (L)中使用一些较小的数字d作为基数,无论是平均密度还是最小密度。

答案 1 :(得分:0)

您还可以对已释放的数字使用排序列表。

设n表示take()函数返回的最大数。 每次调用free(d)时,首先在排序列表中搜索d并在必要时抛出异常!否则,将d插入排序列表。整个操作的成本为O(log n)。

现在,每次调用take()函数时,只需返回其中的最小数字,并使用cost O(1)返回delete-min。如果排序列表为空,则递增n并返回它。

请注意,在这种方法中,它们没有内存开销:)