假设我们有一个包含几百个元素的java.util.LinkedList。在现有元素K之后插入新元素E的一种可能性是:
list.add(list.indexOf(K) + 1, E);
据我所知,这个方法有一个O(k 2 )行为,其中k表示元素K的位置。首先,indexOf()在列表中运行,直到找到K,然后add再次做同样的工作,直到它到达位置k + 1.但是在第一步之后可以很容易地确定必须修改的条目。我认为使用O(k)行为创建方法addAfter(K,E)并不是那么多工作。
除了切换到java.util.ArrayList之外,有没有办法改善像这样的场景中的性能?
提前谢谢。
答案 0 :(得分:4)
你错了你的假设,它是O(k ^ 2),它只是O(2k)是O(k)(这里的Btw必须不是k =元素的索引,但是列表的大小,但是对问题无关紧要)。但你是对的,它需要两倍的时间,而且是无效的。我能想到的唯一方法是使用ListIterator
并自己查找/插入(这是为了完成这种操作)。
答案 1 :(得分:2)
据我所知,这个方法有一个O(k2)行为,其中k表示元素K的位置。首先,indexOf()遍历列表,直到找到K,然后add必须再次做同样的工作,直到它到达位置k + 1。
实际上,如果list.add(list.indexOf(K) + 1, E)
是O(k)
,则list
的费用为LinkedList
。
list.indexOf(K)
来电涉及k
次点击和k
次比赛。
list.add(k + 1, E)
来电涉及k + 1
次网络浏览。
添加它们 - 3 k + 1
操作;即O(k)
。
但是,你是对的。可以使用LinkedList
或addAfter
方法创建addBefore
的替代版本。这些方法也是O(k)
但它们应该更快。遗憾的是,LinkedList
的实现方式不允许您简单地添加这些方法(并以最佳方式实现)。 LinkedList
的内部被声明为私有,因此您需要重新开始。
list.add(list.indexOf(K) + 1, E)
上的ArrayList
O(N)
N
indexOf
,k
列表长度add
。 N - k
步骤需要进行N
次比较,O(N)
步骤涉及移动{{1}}元素。 Ergo {{1}}操作和{{1}}
答案 2 :(得分:1)
这段代码是为了进行k操作:
LinkedList<Integer> list = new LinkedList<Integer>();
for(int i=0;i<100;i++){
list.add(i);
}
Integer insert = 1001;
Integer before = 50;
for (ListIterator<Integer> iterator = list.listIterator(); iterator.hasNext();) {
Integer next = iterator.next();
if(next.equals(before)){
iterator.add(insert);
break;
}
}