在具有initialCapacity = n`的java.util.PriorityQueue`中插入`n`元素的时间复杂度

时间:2019-02-03 09:05:59

标签: java algorithm time-complexity priority-queue

我必须从数组(在下面的代码中称为int indexes[] = { 0, 1, 2, 3 }; // sort indexes <== YOUR TASK // indexes now is { 1, 0, 2, 3 } for (i = 0; i < 4; i++) { printf("%f for %s\n", year2010Cases[indexes[i]], caseName[indexes[i]]); } )中构造一个最大堆,因此我正在使用nums

我的代码如下:

java.util.PriorityQueue

我正在尝试查找上述PriorityQueue<Integer> pq = new PriorityQueue<>(nums.length, (a, b) -> b - a); for (int i = 0; i < nums.length; i++) { pq.offer(nums[i]); } 循环的时间复杂度(以Big-O表示)。

我知道for没有指定底层数据结构增长的详细信息。 (在最坏的情况下,扩展内部数组并在新分配的空间上复制所有元素时,它可能是PriorityQueue

但是我假设当我指定O(n)并且添加的元素不超过此initialCapacity时,上述循环的最坏情况下的时间复杂度应该是initialCapacity而不是O(n)。从here我了解到,堆的构建时间为O(nlog(n)),而O(n)是一个宽松的上限。

我是正确的,还是我缺少什么?

我只是想了解,如果我将nlog(n)中的PriorityQueue配置为initialCapacity并在该优先级队列中添加n元素,那么时间的复杂度是多少这个建筑堆的过程?

PS:我已经看过this,但是针对该问题的答案只是声称没有解释,可能不是Java特有的。

我还看到n具有一个接受java.util.PriorityQueue的构造函数。这将是该构造的时间复杂度?应该不是Collection吗?

1 个答案:

答案 0 :(得分:2)

  

我知道PriorityQueue没有指定底层数据结构增长的详细信息。

让我们对此清楚。 Javadoc 声明,未指定用于扩展队列的策略。

  

(在最坏的情况下,扩展内部数组并在新分配的空间上复制所有元素时,它可能是O(n)。

当前政策(Java 11)为:

    // Double size if small; else grow by 50%
    int newCapacity = oldCapacity + ((oldCapacity < 64) ?
                                     (oldCapacity + 2) :
                                     (oldCapacity >> 1));

对于“双重”保单,每次插入的摊销成本为O(1)。对于增长50%是没有那么好。但比O(n)的方式更好。

可以肯定地说,不管当前的规范(技术上)允许什么,他们都不会单方面将此政策更改为复杂性大大恶化的事情。

但是,这与您的问题没有关系,因为您正在使用initialCapacity容量,无论是显式使用还是从集合中填充PriorityQueue

  

我假设当我指定initialCapacity且添加的元素不超过此`initialCapacity'时,以上循环的最坏情况下的时间复杂度应为O(n)而不是O(nlog(n ))。我从这里了解到,堆的构建时间为O(n),nlog(n)是一个宽松的上限。

     

我是正确的,还是我缺少什么?

我认为您缺少某些东西。

假定您的输入数组未排序,则按顺序构建堆(“堆”)并按顺序检索元素等效于将元素按优先级排序。平均而言,这是一个O(nlogn)操作。虽然堆化本身为O(n)(因为代码使用向下堆化),但实际上您已经推迟了一些排序成本,直到以后。

因此,除非您只打算检索放入队列中的元素的非O(n)子集,否则总的答案是O(nlogn)。

  

我只是想了解,如果我将PriorityQueue中的initialCapacity配置为n并在该优先级队列中添加n元素,那么时间的复杂度是多少这个建筑堆的过程?

由于上述原因,总体复杂度(添加和删除n个元素)将为O(nlogn)。

  

我还看到PriorityQueue有一个接受Collection的构造函数。这将是该构造的时间复杂度?应该不是O(n)吗?

如果集合是未排序的,那么元件必须heapified;往上看。有一些特殊情况下的代码可以处理SortedCollection,从而跳过了堆积步骤。


注意:

  1. 您可以通过阅读PriorityQueue的源代码来确认上面的详细信息。谷歌可以帮您找到它。
  2. HeapSort上的Wikipedia页面谈论堆化
  3. 良好算法的教科书中给出了证明,通过将基于数组的数据结构加倍来实现每次插入O(1)的证明。相同的分析可以应用于增长50%。
  4. 您的lambda表达式(a, b) -> b - a不适用于整数排序,除非它们为正数。