我正在寻找一种数据结构,可以确保至少删除和插入节点的Log(n)复杂度以及接近O(1)或分摊的Log(n)以搜索最大(或最小)值
我正在考虑使用自我平衡的BST(哪一个?)进行修改以记住插入的最大值(或最小值)。
有什么建议吗?
抱歉,我必须编辑问题...当然,自我平衡的BST可以允许在log(n)中搜索max和min,但我正在考虑更多关于O(1)的事情。
答案 0 :(得分:6)
您可以使用任何自平衡BST(例如红黑,AVL)。
如果你跟踪最小值和最大值,获取它们的查询将采用O(1)。
由于最小值和最大值只能在插入和删除时更改,因此在执行这些操作时(基本上它们的运行时间仍为O(log n))基本上可以重新确定它(在O(log n)中)。
虽然在收到查询时最重新确定最小值或最大值可能更好一点,并且自上次查询以来有插入或删除。
它也可能更加聪明 - 如果你到目前为止只离开了,你是最小的,如果你只是走了,你就是最大的。插入时,只需更换最小值/最大值即可。删除时,只需在已删除节点的树中查看,即可找到新的最小值/最大值。
答案 1 :(得分:1)
此处查找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。您必须稍微修改才能添加尾指针,但除此之外,它还可以执行您想要的所有操作。随着修改:
跳过列表并不比二进制堆更难实现,而且我记得,实现平衡二叉树要容易得多。我能够从original paper实现它,它比我见过的大多数学术论文都有更好的描述。
答案 4 :(得分:0)
评论已经讨论了双端堆,并得出结论认为它不合适,因为删除需要知道元素的位置。我认为这可以修复,在许多情况下是合理的,如下所示:保持两个双端堆,一个(比如A)输入到集合中的条目和一个(比如说B)条目被删除。
这将为您提供O(log(k))插入和删除,并分摊O(1)最小/最大计算。但是,在这种情况下,k是插入到集合中但尚未从A和B中弹出的元素数量;更明显的其他解决方案具有复杂性,具体取决于集合中实际元素的数量(即插入但尚未删除的元素) - 让我们称这个数字为n。你可以提出k比n大得多的场景,这与其他解决方案没有竞争力 - 以及k和n大致相等的其他场景,这个解决方案更快。所以这取决于你的应用是否这是一个好主意。