从集合构造 PriorityQueue 的时间复杂度是多少?

What is the time complexity of constructing a PriorityQueue from a collection?

Java 的 PriorityQueue 构造函数与 Collection 的复杂性如何? 我使用了构造函数:

PriorityQueue(Collection<? extends E> c)

复杂度是O(n)还是O(n*log(n))?

从集合(即使是未排序的集合)中初始化 PriorityQueue 的时间复杂度为 O(n)。这在内部使用一个名为 siftDown() 的过程到 "heapify" 数组 in-place。 (这在文献中也被称为下推。)

这是违反直觉的。将一个元素插入堆中似乎是 O(log n),因此插入 n 个元素会导致 O(n log n) 复杂度。如果您一次插入一个元素,就会出现这种情况。 (在内部,插入单个元素使用 siftUp() 执行此操作。)

堆化一个单独的元素当然是O(log n),但是siftDown()的"trick"是在处理每个元素时,它必须筛选过去的元素数量是不断减少。所以总复杂度不是 n 个元素乘以 log(n);它是筛选剩余元素的递减成本的 n 项之和。

请参阅 this answer, and see also this article 通过数学计算得出的结果。