当前位置: 首页 > 知识库问答 >
问题:

在endpoint和元素之前/之后以恒定时间插入的数据结构?

祁曦哲
2023-03-14

我正在寻找一种数据结构:

  • 具有无界的大小。
  • 保持其元素的插入顺序。
  • 在列表的开头和结尾有效地插入(理想情况下为常量时间)。
  • 在现有元素之前或之后有效地插入(理想情况下是在恒定时间内)。

我排除了ArrayList,因为它在列表开头插入时效率不高。

表面上LinkedList应该是一个完美的匹配,但实际上Java实现在插入现有元素之前或之后并不有效(即它遍历整个列表以查找插入位置)。

(我个人不需要存储重复的元素,但其他人可能会)

动机:我正在构建一个允许偶尔作弊的事件队列(在现有事件之前或之后插入)。

共有3个答案

伊锦
2023-03-14

我正在构建一个允许偶尔作弊的事件队列(在现有事件之前或之后插入)。

如果作弊很少,那就选择你自己的基于数组的结构。java.util.ArrayDeque在O(1)中处理两端,但它不能在中间进行插入。它们可以很容易地添加,但复杂性是O(n)。

请注意,LinkedList对于大多数操作(由于其糟糕的数据局部性)比ArrayListArrayDeque慢得多。

让我们假设,你非常需要在中间插入恒定的时间。差不多

insertAfter(existingElement, newElement);

java的问题。util。LinkedList就是它没有这样的操作。它所拥有的是 ListItRealter < /Cord>,它允许你在中间插入,但是只有当你先定位你的迭代器(O(n))时才有帮助。

所以你需要自己的链表。基本实现相当简单,您还需要直接访问其节点(包含nextprev链接的内容,而不是添加的内容)。然后维护一张地图

要消除边界情况(第一个/最后一个/唯一的节点),请在链接列表中添加两个虚拟节点(prefirstpostlast)。显然,这些是唯一不会存储在地图中的节点。它们使实现变得非常简单,例如。,

void insertAfter(MyThing existingElement, MyThing newElement) {
   Node found = map.get(existingElement);
   if (found == null) throw ...
   Node newNode = new Node(newElement);
   map.put(newElement, newNode);

   // Link newNode where it belongs to.
   newNode.next = found.next;
   newNode.prev = found;

   // Fix links.
   newNode.prev.next = newNode;
   newNode.next.prev = newNode;   
}

void insertFirst(MyThing newElement) {
   Node found = prefirst;

   // All the remaining code is simply copied from above.
   // Factor it out.

   Node newNode = new Node(newElement);
   map.put(newElement, newNode);

   // Link newNode where it belongs to.
   newNode.next = found.next;
   newNode.prev = found;

   // Fix links.
   newNode.prev.next = newNode;
   newNode.next.prev = newNode;   
}

江阳夏
2023-03-14

AVL树怎么样?因为树总是平衡的,所以它的高度为O(log(N)),其中N是树中的节点数。这将使最坏情况下的插入也为O(log(N))。

我相信对于你所寻找的东西来说,这是尽可能接近恒定的时间。抱歉,如果这不是答案,我的声誉还不足以发表评论:/

汲涵育
2023-03-14

老实说,我认为一个LinkedList的定制实现将是最好的选择:

  • 具有无界大小。
    • 是的。
    • 是的,还有O(1)
    • 如果你维护一张地图

    根据事件的总量(以及事件作弊的频率),还可以考虑使用线性时间,从而允许您使用API的LinkedList实现。

 类似资料:
  • 问题内容: 这是我的代码,也许您会立即注意到我所缺少的内容: 我正在尝试在CustomerId现有节点之前插入新的node()。这是我的XML示例文件: 这是一个抛出异常,我只是不知道还能尝试什么: NOT_FOUND_ERR:尝试在不存在的上下文中引用该节点。 问题答案: 在这里,我只是使用您提供的xml示例进行了测试的示例。 结果如下: 如果您有兴趣,这是我用来显示结果的示例代码:

  • 问题内容: 我对了解何时可以将和伪元素应用于自动关闭标签特别感兴趣。根据W3生成的内容CSS规范,这是这些伪元素的定义: 12.1:before和:after伪元素 :作者使用 :before和:after伪元素 指定生成内容的样式和位置。顾名思义,:before和:after伪元素指定元素的文档树内容之前和之后的内容位置。“ content”属性与这些伪元素一起指定了要插入的内容。 基于此,这些

  • 问题内容: 假设我有一个这样的Python清单: 我想在每个第n个元素后插入一个“ x”,比方说该列表中的三个字符。结果应为: 我知道我可以通过循环和插入来做到这一点。我实际上正在寻找的是Pythonish方式,也许是单线? 问题答案: 我有两个一线客轮。 鉴于: 使用获得指数,增加每3次字母, 如 :,然后连接成字符串和它。 [‘a’, ‘b’, ‘c’, ‘x’, ‘d’, ‘e’, ‘f’,

  • 我编写了一个函数,用于在给定范围之前或之后截断数据。我传入一个日期元组,位置1是开始日期,位置2是结束日期。 我如何也可以选择指定截断b4和b4之后的时间和日期-我将如何使用我的代码来做到这一点?*) 此外-我一直在我的数据上得到一个错误,说: 我使用: 我的日期元组: 这是数据集的my df.head(): 我已经运行了下面的程序来检查索引中的dupilcates,它返回NAT,所以我不确定为什

  • 本文向大家介绍java数据结构之插入排序,包括了java数据结构之插入排序的使用技巧和注意事项,需要的朋友参考一下 插入排序就是把当前待排序的元素插入到一个已经排好序的列表里面。 一个非常形象的例子就是右手抓取一张扑克牌,并把它插入左手拿着的排好序的扑克里面。          插入排序的最坏运行时间是O(n2), 所以并不是最优的排序算法。          如果输入数组已经是排好序的话,插入排

  • 问题内容: 在Firefox 3和Google Chrome 8.0中,以下功能可以正常运行: 但是当元素为时不是这样: 为什么它不按我的预期工作? 问题答案: 使用和指定要在该元素内部 的内容 之前(或之后)插入 的内容 。元素没有内容。 例如,如果你写的(这是错误的),浏览器会纠正这一点,并把文字 后 输入元素。 您唯一可以做的就是将每个输入元素包装在span或div中,然后将CSS应用于这些