我应该使用哪种数据结构进行快速删除/插入和最大(或最小)搜索?

时间:2013-10-29 16:21:13

标签: algorithm data-structures

我正在寻找一种数据结构,可以确保至少删除和插入节点的Log(n)复杂度以及接近O(1)或分摊的Log(n)以搜索最大(或最小)值

我正在考虑使用自我平衡的BST(哪一个?)进行修改以记住插入的最大值(或最小值)。

有什么建议吗?

抱歉,我必须编辑问题...当然,自我平衡的BST可以允许在log(n)中搜索max和min,但我正在考虑更多关于O(1)的事情。

5 个答案:

答案 0 :(得分:6)

您可以使用任何自平衡BST(例如红黑,AVL)。

如果你跟踪最小值和最大值,获取它们的查询将采用O(1)。

由于最小值和最大值只能在插入和删除时更改,因此在执行这些操作时(基本上它们的运行时间仍为O(log n))基本上可以重新确定它(在O(log n)中)。

虽然在收到查询时最重新确定最小值或最大值可能更好一点,并且自上次查询以来有插入或删除。

它也可能更加聪明 - 如果你到目前为止只离开了,你是最小的,如果你只是走了,你就是最大的。插入时,只需更换最小值/最大值即可。删除时,只需在已删除节点的树中查看,即可找到新的最小值/最大值。

答案 1 :(得分:1)

您可以使用red-black树或AVL tree

此处查找min-max,删除节点为O(LogN)

根据问题的最新编辑,我建议你使用数据结构,通过修改的堆栈可以在O(1)中给你O(1)min / max,插入和删除。如果有兴趣我可以继续。这一切都取决于您的需求,您想要找到最小值/最大值的频率,您想要插入的位置,删除所有这些的特定元素。

答案 2 :(得分:1)

AVL适合:搜索max和min是O(log n),因为min是最左边的节点,max是最右边的节点,树是平衡的。如果您只删除最大/最小节点,这也是O(log n),但只有在删除节点时才会使树不平衡。

答案 3 :(得分:1)

我为此使用skip list。您必须稍微修改才能添加尾指针,但除此之外,它还可以执行您想要的所有操作。随着修改:

  • 首先找到O(1)
  • 首先删除是O(1)
  • 最后找到O(1)
  • 删除最后是O(1)
  • 查找任意节点为O(log n)
  • 删除任意节点为O(log n)

跳过列表并不比二进制堆更难实现,而且我记得,实现平衡二叉树要容易得多。我能够从original paper实现它,它比我见过的大多数学术论文都有更好的描述。

答案 4 :(得分:0)

评论已经讨论了双端堆,并得出结论认为它不合适,因为删除需要知道元素的位置。我认为这可以修复,在许多情况下是合理的,如下所示:保持两个双端堆,一个(比如A)输入到集合中的条目和一个(比如说B)条目被删除。

  • 要将元素插入集合,请将其插入A。
  • 要从集中删除元素,请插入B。
  • 要获得最大值:如果B为空,则只返回A的最大值。否则,让mA为A的最大值和B的最大值。如果mA> mB,然后mA没有被删除,你可以返回它。如果mA = mB,则它被删除,你应该从A弹出mA,从B弹出mB,然后从这个项目符号点的开头开始。你不能有mA< MB。
  • 要获得最低限度的设置,请以明显的方式调整最大程序。

这将为您提供O(log(k))插入和删除,并分摊O(1)最小/最大计算。但是,在这种情况下,k是插入到集合中但尚未从A和B中弹出的元素数量;更明显的其他解决方案具有复杂性,具体取决于集合中实际元素的数量(即插入但尚未删除的元素) - 让我们称这个数字为n。你可以提出k比n大得多的场景,这与其他解决方案没有竞争力 - 以及k和n大致相等的其他场景,这个解决方案更快。所以这取决于你的应用是否这是一个好主意。