优先队列其实就是由各种堆实现,最大堆可以实现最大优先队列,最小堆可以实现最小优先队列。
可以参考以下文章:
优先队列(PriorityQueue) - 简书 (jianshu.com)
排序算法-堆排序和时间复杂度_阿巴卡的博客-CSDN博客_堆排序时间复杂度
优先队列(priority queue)_csuzhucong的博客-CSDN博客_优先队列
本文就时间复杂度进行分析:
1. 从一个无序的序列调整成最大堆(最小堆)的形式,时间复杂度为O(n),理由如下:
该调整方法是从 n 2 \frac{n}{2} 2n开始(可以证明 n 2 \frac{n}{2} 2n是从后往前看第一个非叶子结点),对每个非叶子节点进行下沉操作
某个节点进行下沉操作的时间复杂度与该节点所在的高度成正比(因为需要与它的两个孩子对比,下去之后继续跟两个孩子对比,直至到达叶子节点或者不用下去)
那么总的时间复杂度与 所有非叶子节点的高度之和 成正比
一共
h
h
h层,第
i
i
i层有
2
i
2^{i}
2i个节点,高度为
h
−
i
h-i
h−i
S
=
2
0
∗
h
+
2
1
∗
(
h
−
1
)
+
⋯
+
2
i
∗
(
h
−
i
)
+
⋯
+
2
h
−
1
∗
(
h
−
(
h
−
1
)
)
S = 2^0 * h + 2^1 * (h-1) + \cdots + 2^i * (h-i) + \cdots + 2^{h-1} * (h-(h-1))
S=20∗h+21∗(h−1)+⋯+2i∗(h−i)+⋯+2h−1∗(h−(h−1))
S
=
2
S
−
S
=
2
1
∗
h
+
2
2
∗
(
h
−
1
)
+
⋯
+
2
h
−
1
∗
(
h
−
(
h
−
2
)
)
+
2
h
∗
(
h
−
(
h
−
1
)
)
−
S
=
−
2
0
∗
h
+
2
1
+
⋯
+
2
h
−
1
+
2
h
∗
(
h
−
(
h
−
1
)
)
=
−
h
+
2
h
−
2
+
2
h
=
2
h
+
1
−
h
−
2
由
2
0
+
2
1
+
⋯
+
2
h
=
n
2^0+2^1+\cdots+2^h=n
20+21+⋯+2h=n可得
h
=
l
o
g
2
(
n
+
1
)
−
1
=
O
(
l
o
g
2
n
)
h=log_2(n+1) - 1=O(log_2n)
h=log2(n+1)−1=O(log2n),所以
S
=
n
−
l
o
g
2
(
n
+
1
)
−
2
=
O
(
n
)
S=n-log_2(n+1)-2=O(n)
S=n−log2(n+1)−2=O(n)。
2. 堆排序的时间复杂度为 O ( n l o g 2 n ) O(nlog_2n) O(nlog2n),理由如下:
以大顶堆为例,分为两部分:
由于对根节点的下沉操作的时间复杂度与整个堆的高度
h
h
h成正比,而高度
h
=
O
(
l
o
g
2
n
)
h=O(log_2n)
h=O(log2n),其中
n
n
n一直在变,可以发现第二部分的时间复杂度为:
S
=
l
o
g
2
n
+
l
o
g
2
(
n
−
1
)
+
⋯
+
l
o
g
2
1
=
l
o
g
2
(
n
!
)
可以证明
l
o
g
2
(
n
!
)
和
n
l
o
g
2
n
log_2 (n!)和nlog_2 n
log2(n!)和nlog2n是同阶函数:
n
2
n
2
≤
n
!
≤
n
n
1
4
n
l
o
g
(
n
)
≤
n
2
l
o
g
(
n
1
2
)
≤
n
2
l
o
g
(
n
2
)
≤
n
!
≤
n
l
o
g
(
n
)
\frac{n}{2}^{\frac{n}{2}} \le n! \le n^n \\ \frac{1}{4}nlog(n) \le \frac{n}{2}log(n^{\frac{1}{2}}) \le \frac{n}{2} log(\frac{n}{2}) \le n! \le nlog(n)
2n2n≤n!≤nn41nlog(n)≤2nlog(n21)≤2nlog(2n)≤n!≤nlog(n)
所以,第二部分的时间复杂度
S
=
O
(
n
l
o
g
(
n
)
)
S=O(nlog(n))
S=O(nlog(n)),由于第一部分的时间复杂度为
O
(
n
)
O(n)
O(n),所以总的时间复杂度为
O
(
n
l
o
g
(
n
)
)
O(nlog(n))
O(nlog(n))。