具有快速搜索和插入的类似队列的数据结构

时间:2010-04-15 21:43:49

标签: performance data-structures

我需要一个具有以下属性的数据结构:

  1. 它包含整数。
  2. 不允许重复(即,它最多存储一个整数)。
  3. 在达到最大尺寸后,第一个元素被移除。 因此,如果容量为3,那么这就是将序列号放入时的样子: {},{1},{1,2},{1,2,3},{2,3,4},{3,4,5}等。
  4. 只需要两个操作:在此容器中插入一个数字(INSERT)并检查该数字是否已经在容器中(EXISTS)。 EXISTS操作的数量预计约为INSERT操作的2 *。
  5. 我需要这些操作尽可能快。
  6. 此方案的最快数据结构或数据结构组合是什么?

4 个答案:

答案 0 :(得分:3)

听起来像是使用环形缓冲区进行存储的哈希表。

答案 1 :(得分:2)

O(1)用于插入和查找(如果最终需要,则删除)

数据结构:

包含整数的节点队列,实现为链接列表(queue

HashMap将整数映射到Queue的链表节点(hashmap

插入

if (queue.size >= MAX_SIZE) {
    // Remove oldest int from queue and hashmap
    hashmap.remove(queue.pop());
} else if (!hashmap.exists(newInt)) { // remove condition to allow dupes.
    // add new int to queue and hashmap if not already there
    Node n = new Node(newInt);
    queue.push(n);
    hashmap.add(newInt, n);
}

<强>查找

return hashmap.exists(lookupInt);

注意:使用此实现,您还可以删除O(1)中的整数,因为您只需要在散列映射中查找节点,然后将其从链接列表中删除(通过将其邻居链接在一起)。

答案 2 :(得分:0)

你想要一个环形缓冲区,最好的方法是定义一个你想要的大小的数组,然后维护索引的开始和结束位置。

int *buffer = {0,0,0};
int start = 0;
int end = 0;
#define LAST_INDEX 2;

void insert(int data)
{
   buffer[end] = data;
   end = (end == LAST_INDEX) ? 0 : end++;
}
void remove_oldest()
{
   start = (start == LAST_INDEX) ? 0 : start++;    
}
void exists(int data)
{
   // search through with code to jump around the end if needed
}

start始终指向第一个项目 结束总是指向最近的项目 列表可以包裹在数组的末尾

搜索n logn 插入1 删除1

对于真正的极客标记虽然构建了Bloom过滤器http://en.wikipedia.org/wiki/Bloom_filter 不保证100%准确,但比任何事情都快。

答案 3 :(得分:0)

如果要删除最低值,请使用排序列表,如果您有多于所需的元素,请删除最低值。

如果要删除最旧的值,请使用集和队列。集合和队列都包含每个值的副本。如果值在集合中,则为no-op。如果该值不在集合中,则将值附加到队列并将其添加到集合中。如果您已超出大小,请弹出队列并从集合中删除该值。

如果需要将重复值移动到队列的后面,则需要从一个集合切换到哈希表,将值映射到队列中的稳定迭代器,并能够从队列中间删除。

或者,您可以使用排序列表和哈希表。您可以成对(id,value),然后将哈希表映射从值到(id,value),而不是仅将值放入排序列表中。 id会在每次插入后递增。当您在哈希表中找到匹配项时,从列表中删除该项(id,value)并在列表末尾添加新的(id,value)对。否则你只需添加到列表的末尾,如果它太长就从头开始弹出。