具有恒定插入时间的数据结构,包含,删除和按索引获取元素

时间:2017-10-19 04:08:44

标签: java arraylist data-structures time-complexity

我有一个Person个对象的大型数据集,这些对象在列表中排队。我希望数据结构能够有效地执行以下操作。

  1. 在队列末尾添加Person
  2. 删除第一个Person
  3. 查找特定Person是否存在,如果存在,请将其删除并将其放在队列末尾。
  4. 根据其位置获取特定Person
  5. 所有这些操作都可以有O(1)时间吗? 到目前为止,我已经提出了两种方法,但它们并不是最优的。

    1. ArrayList<Person> + HashMap<Person, Integer>

      HashMap存储Person个对象的索引。这为操作2和3提供了O(n)时间(删除ArrayList中的元素)

    2. ArrayDeque<Person> / LinkedList<Person>

      他们为前2个操作提供O(1),但为最后两个操作提供O(n)。

    3. 在我的情况下,空间复杂度不得大于O(n)。操作4的密集度较低,因此我可以容忍一种效率稍低的方法。

      任何建议将不胜感激。提前谢谢!

2 个答案:

答案 0 :(得分:3)

我认为要求3意味着&#34;通过某个键找到一个人&#34; (例如它的姓氏)?

我有一种强烈的感觉,你不能在O(1)中拥有所有这些要求,甚至没有摊销时间(这样的事情是众所周知的)。但是你可以将它们全部放在O(log N)中。你必须从一个红黑树的实现开始(在C ++中使用std :: map,我相信这是Java中的SortedMap),并修改节点结构以保持其子节点中所有节点的数量。树。这将通过索引为您提供O(log N)访问,以及在树中的任何位置插入和删除O(log N)。通过某个键找到一个人可以通过外部哈希表(红黑树节点)在O(1)中完成。

如果您对O(N)的要求4没有问题,那么我建议在Java中使用像LinkedHashMap这样的东西,它在O(1)中给出了要求1到3,而req。 4可以通过在O(N)中迭代来完成。

答案 1 :(得分:2)

如果问题尚未标记为java,而是c++,则std::dequestd::unordered_map的组合几乎就足够了。我说几乎是因为第三个请求相当复杂,我不知道如何在O(1)中结合其他三个请求。

std::unordered_map在Java中具有等效的HashMap,但std::deque提供的内容和ArrayDeque不提供,O(1)随机访问 - &gt;您的请求编号四。即使它has already been discussedArrayDeque中仍然缺少此功能,但我认为手动添加它并不困难。毕竟,std::deque只是一个带有固定大小缓冲区指针的向量。

在任何体面的deque实现中,前两个操作都是O(1)。根据第3号请求,HashMap(或std::unordered_map)会在Person时间内向您提供特定O(1)是否存在的信息,您可以将其放在最后同样的复杂性。删除是一个问题,因为必须移动其他元素,并且使用此策略无法在O(1)中获取。