【问题标题】:A data structure traversable by both order of insertion and order of magnitude可按插入顺序和数量级遍历的数据结构
【发布时间】:2015-07-01 13:04:39
【问题描述】:

有没有一种数据结构可以在O(n)中同时按插入顺序和数量级遍历,最多O(log(n))次插入和删除?

换句话说,给定元素 5、1、4、3、2(按此顺序插入),可以在 O(n) 时间内以 1,2,3,4,55,1,4,3,2 的形式遍历它。

当然,我可以使用数组并在遍历之前简单地对其进行排序,但这需要 O(n*log(n)) 预遍历步骤。另外,我可以使用多链表来实现 O(n) 的遍历,但是在这种情况下插入和删除操作也会花费 O(n),因为我不能保证最新的元素一定是最大的。

如果存在这样的数据结构,请给我一个正式的名称,以便我可以进一步研究它,或者如果它没有,一个简短的表面级描述将不胜感激。

谢谢

【问题讨论】:

  • 列表+二叉搜索树呢?
  • 如果存在这样的结构,我会感到惊讶。您当然可以简单地构建两个排序树,例如,或者一个排序树和一个链表。
  • @DavidEisenstat 是的,我也在考虑同样的思路,但我不确定如何连接它们,以便当我从一个元素中删除一个元素时,它将在 sub 中从另一个元素中删除-O(n) 时间。
  • @G.Bach 我也是,但我想我会问一下以防万一。
  • 树和列表组合实际上可能有效,但我需要注意如何链接元素。

标签: algorithm sorted inorder


【解决方案1】:

还允许次线性删除的一种解决方案是构建一个数据结构D,它使用链表D.L 进行按插入顺序的遍历,并使用排序树D.T 按数量级进行遍历。但是如何链接它们以在亚线性时间内额外实现删除操作?诀窍是D.T 应该存储,而只是D.L 中相应链表元素的引用

插入:在 O(1) 时间内附加到 D.L,并在 O(log(n)) 时间内将对附加元素的引用插入到 D.TD.T 中的任何比较当然是根据引用的值进行的,而不是引用本身)

按插入顺序(或向后)遍历:只需在 O(n) 时间内线性遍历 D.L

按数量级(或向后)遍历:只需在 O(n) 时间内通过 tree-walk 遍历 D.T

删除:首先在 O(log n) 时间内找到并删除D.T 中的元素,这也为您提供了对D.L 的正确元素引用,因此可以从D.L 中删除它在 O(1) 时间内。

【讨论】:

  • 这听起来像是将树和列表链接起来,对吗?
  • 很好的解释!谢谢!这很有意义!
【解决方案2】:

评论者是对的:最好的办法是将对象存储两次:一次在链表中(插入顺序),一次在二叉树中(内在排序顺序)。

这并不像听起来那么糟糕,因为您不必复制对象,因此唯一的成本是列表/树脚手架,这将花费您存储的每个对象 4 个机器字。

【讨论】:

  • 我接受了另一个答案来解释它,但我仍然非常感谢您对脚手架成本的洞察力,因为这有助于我了解这将如何影响性能。谢谢!
【解决方案3】:

您甚至不需要两个数据结构。只需使用二叉树,而不是插入您的对象,而是将其包装在一个对象中,该对象还包含指向前一个和下一个对象的指针。这在 java 等主流语言中是相当简单的,您可以使用带有比较器的默认树实现来按属性对树进行排序。

只要保留对第一个和最后一个元素的引用,就可以使用对象的内部指针按顺序遍历它们。

【讨论】:

  • 好主意菲尔!谢谢!对我来说,实现起来可能有点困难,因为我需要在 C 中执行此操作,但这个技巧可能对可能遇到此问题的其他人有所帮助。 :) 谢谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-10-09
相关资源
最近更新 更多