是否有一个数据结构可以按插入顺序和O(n)中的数量级进行遍历,最多插入和删除O(log(n))?
换句话说,给定元素5,1,4,3,2(按此顺序插入),它可以在O(n)时间内以1,2,3,4,5
或5,1,4,3,2
遍历。< / p>
当然我可以使用数组并在遍历之前对其进行排序,但这需要一个O(n * log(n))预遍历步骤。此外,我可以使用多链表实现O(n)遍历,但在这种情况下,插入和删除操作也将采用O(n),因为我无法保证最新元素必然是最大的。
如果存在这样的数据结构,请为我提供一个正式的名称,以便我可以进一步研究,或者如果没有,我们将不胜感激。
谢谢
答案 0 :(得分:3)
一个允许次线性删除的解决方案是构建一个数据结构*pA
,它使用链接列表D
按插入顺序进行遍历,并使用排序树D.L
进行插入。遍历数量级。但是如何将它们连接起来以在次线性时间内另外实现删除操作?诀窍是D.T
应该不存储值,而只是对{{1>中相应链表元素的引用 }}
插入:在时间O(1)中附加到D.T
,并在时间O(log(n))中将附加元素的引用插入D.L
。 D.L
中的任何比较当然都是根据参考值进行的,而不是通过引用来进行的比较。
按插入顺序(或向后)进行遍历:简单地在时间O(n)中线性遍历D.T
按数量级(或向后)遍历:只需在时间O(n)中通过树步行遍历D.T
删除:首先在时间O(log n)中查找并删除D.L
中的元素,这也为D.T
提供了正确的元素引用,因此它可以在时间O(1)中被移除D.T
。
答案 1 :(得分:2)
评论者是对的:最好的办法是将对象存储两次:一次在链表中(插入顺序),一次在二叉树中(内在排序顺序)。
这并不像听起来那么糟糕,因为您不必复制对象,因此唯一的成本是列表/树脚手架,并且每个对象存储4个机器字。
答案 2 :(得分:1)
您甚至不需要两个数据结构。只需使用二叉树,而不是插入对象,将其包装在一个对象中,该对象还包含指向前一个和下一个对象的指针。在像java这样的主流语言中这很简单,你可以使用带有比较器的默认树实现来按属性对树进行排序。
只要保留对第一个和最后一个元素的引用,就可以使用对象的内部指针遍历它们。