我想知道PriorityQueue.Add()
元素的Java n
的时间复杂度。
我理解可能更糟糕的情况是单个元素插入O(log(n))
,但我不清楚插入n
元素集合的时间复杂度是多少?
我已经看到各种来源(没有证据)声称构建n
元素的优先级队列堆的时间是O(n)
,并且还看到声称它是O(nlog(n))
,在插入时有意义O(log(n))
,乘以n
次,确实等于O(nlog(n))
注意:我只对最坏情况感兴趣,而不是摊销。
这个问题假设有一种逻辑方式来描述使用n
元素填充数据结构(堆)的行为,这与仅单独考虑n
x log(n)
个插入不同
我没有对输入做出任何假设(例如输入值集合的边界或部分有序的输入)。
答案 0 :(得分:8)
似乎n个元素的插入应该是O(n log n)
Java PriorityQueue (Java Doc)
O(log n)时间的排队和出队方法(报价,民意调查, remove()和add)
O(n)用于remove(Object)和contains(Object)方法
O(1)用于检索方法(窥视,元素和大小)
除了.add()
之外,这些时间复杂度似乎都是最糟糕的情况(wiki)。您正确地质疑边界,因为Java Doc也声明了这个未绑定结构的扩展:
未指定增长政策的详细信息
正如他们在Doc中所述,PriorityQueue基于具有特定初始容量的阵列。我认为增长将耗费O(n)时间,这也是.add()
的最坏情况时间复杂度。
要获得有保证的O(n log n)时间来添加n个元素,您可以说明n个元素的大小以省略容器的扩展:
PriorityQueue(int initialCapacity)
修改强> 对O(n)施工时间的要求是正确的(如评论中@pjs所述)。此过程通常称为heapify,适用于预先存在的数组,该数组用于在O(n)时间内在其上构建二叉树。
答案 1 :(得分:1)
一般情况下是 O(N log N)。对于已经对输入进行排序的特殊情况,存在 O(N)算法,但java.util.PriorityQueue
中未提供此算法。