> 技术文档 > 初识数据结构——优先级队列(堆!堆!堆!)_优先对列大根堆

初识数据结构——优先级队列(堆!堆!堆!)_优先对列大根堆


初识数据结构——优先级队列(堆!堆!堆!)_优先对列大根堆
初识数据结构——优先级队列(堆!堆!堆!)_优先对列大根堆
⬅(click)


今天就让我们来聊聊这个让无数程序员又爱又恨的数据结构——堆(Heap)。

一、优先级队列 vs 普通队列

特性 普通队列 优先级队列 出队顺序 FIFO(先进先出) 按优先级高低(默认小的先出) 底层实现 数组/链表 通常用堆实现 时间复杂度 O(1) 插入O(logN),删除O(logN) Java实现 Queue接口 PriorityQueue类 典型应用场景 消息队列、BFS算法 任务调度、TopK问题

#mermaid-svg-fnKRHWnNPAA5TtVk {font-family:\"trebuchet ms\",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-fnKRHWnNPAA5TtVk .error-icon{fill:#552222;}#mermaid-svg-fnKRHWnNPAA5TtVk .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-fnKRHWnNPAA5TtVk .edge-thickness-normal{stroke-width:2px;}#mermaid-svg-fnKRHWnNPAA5TtVk .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-fnKRHWnNPAA5TtVk .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-fnKRHWnNPAA5TtVk .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-fnKRHWnNPAA5TtVk .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-fnKRHWnNPAA5TtVk .marker{fill:#333333;stroke:#333333;}#mermaid-svg-fnKRHWnNPAA5TtVk .marker.cross{stroke:#333333;}#mermaid-svg-fnKRHWnNPAA5TtVk svg{font-family:\"trebuchet ms\",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-fnKRHWnNPAA5TtVk .label{font-family:\"trebuchet ms\",verdana,arial,sans-serif;color:#333;}#mermaid-svg-fnKRHWnNPAA5TtVk .cluster-label text{fill:#333;}#mermaid-svg-fnKRHWnNPAA5TtVk .cluster-label span{color:#333;}#mermaid-svg-fnKRHWnNPAA5TtVk .label text,#mermaid-svg-fnKRHWnNPAA5TtVk span{fill:#333;color:#333;}#mermaid-svg-fnKRHWnNPAA5TtVk .node rect,#mermaid-svg-fnKRHWnNPAA5TtVk .node circle,#mermaid-svg-fnKRHWnNPAA5TtVk .node ellipse,#mermaid-svg-fnKRHWnNPAA5TtVk .node polygon,#mermaid-svg-fnKRHWnNPAA5TtVk .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-fnKRHWnNPAA5TtVk .node .label{text-align:center;}#mermaid-svg-fnKRHWnNPAA5TtVk .node.clickable{cursor:pointer;}#mermaid-svg-fnKRHWnNPAA5TtVk .arrowheadPath{fill:#333333;}#mermaid-svg-fnKRHWnNPAA5TtVk .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-fnKRHWnNPAA5TtVk .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-fnKRHWnNPAA5TtVk .edgeLabel{background-color:#e8e8e8;text-align:center;}#mermaid-svg-fnKRHWnNPAA5TtVk .edgeLabel rect{opacity:0.5;background-color:#e8e8e8;fill:#e8e8e8;}#mermaid-svg-fnKRHWnNPAA5TtVk .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-fnKRHWnNPAA5TtVk .cluster text{fill:#333;}#mermaid-svg-fnKRHWnNPAA5TtVk .cluster span{color:#333;}#mermaid-svg-fnKRHWnNPAA5TtVk div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\"trebuchet ms\",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-fnKRHWnNPAA5TtVk :root{--mermaid-font-family:\"trebuchet ms\",verdana,arial,sans-serif;} 队列 普通队列 优先级队列 FIFO 基于优先级 实现方式 堆 有序数组 无序数组

二、堆:一棵\"偏心的\"完全二叉树

堆的类型对比

类型 特点 应用场景 大根堆 父节点 ≥ 子节点 堆排序(升序)、TopK最小 小根堆 父节点 ≤ 子节点 堆排序(降序)、TopK最大 二叉堆 完全二叉树实现,常用数组存储 最常用实现 斐波那契堆 更优的理论时间复杂度,但实现复杂 图算法优化
// 堆的数组表示parent(i) = (i-1)/2 // 找父节点left(i) = 2*i + 1 // 左孩子right(i) = 2*i + 2 // 右孩子

#mermaid-svg-BW9lGVs5jbmCEXX0 {font-family:\"trebuchet ms\",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-BW9lGVs5jbmCEXX0 .error-icon{fill:#552222;}#mermaid-svg-BW9lGVs5jbmCEXX0 .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-BW9lGVs5jbmCEXX0 .edge-thickness-normal{stroke-width:2px;}#mermaid-svg-BW9lGVs5jbmCEXX0 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-BW9lGVs5jbmCEXX0 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-BW9lGVs5jbmCEXX0 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-BW9lGVs5jbmCEXX0 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-BW9lGVs5jbmCEXX0 .marker{fill:#333333;stroke:#333333;}#mermaid-svg-BW9lGVs5jbmCEXX0 .marker.cross{stroke:#333333;}#mermaid-svg-BW9lGVs5jbmCEXX0 svg{font-family:\"trebuchet ms\",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-BW9lGVs5jbmCEXX0 .label{font-family:\"trebuchet ms\",verdana,arial,sans-serif;color:#333;}#mermaid-svg-BW9lGVs5jbmCEXX0 .cluster-label text{fill:#333;}#mermaid-svg-BW9lGVs5jbmCEXX0 .cluster-label span{color:#333;}#mermaid-svg-BW9lGVs5jbmCEXX0 .label text,#mermaid-svg-BW9lGVs5jbmCEXX0 span{fill:#333;color:#333;}#mermaid-svg-BW9lGVs5jbmCEXX0 .node rect,#mermaid-svg-BW9lGVs5jbmCEXX0 .node circle,#mermaid-svg-BW9lGVs5jbmCEXX0 .node ellipse,#mermaid-svg-BW9lGVs5jbmCEXX0 .node polygon,#mermaid-svg-BW9lGVs5jbmCEXX0 .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-BW9lGVs5jbmCEXX0 .node .label{text-align:center;}#mermaid-svg-BW9lGVs5jbmCEXX0 .node.clickable{cursor:pointer;}#mermaid-svg-BW9lGVs5jbmCEXX0 .arrowheadPath{fill:#333333;}#mermaid-svg-BW9lGVs5jbmCEXX0 .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-BW9lGVs5jbmCEXX0 .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-BW9lGVs5jbmCEXX0 .edgeLabel{background-color:#e8e8e8;text-align:center;}#mermaid-svg-BW9lGVs5jbmCEXX0 .edgeLabel rect{opacity:0.5;background-color:#e8e8e8;fill:#e8e8e8;}#mermaid-svg-BW9lGVs5jbmCEXX0 .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-BW9lGVs5jbmCEXX0 .cluster text{fill:#333;}#mermaid-svg-BW9lGVs5jbmCEXX0 .cluster span{color:#333;}#mermaid-svg-BW9lGVs5jbmCEXX0 div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\"trebuchet ms\",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-BW9lGVs5jbmCEXX0 :root{--mermaid-font-family:\"trebuchet ms\",verdana,arial,sans-serif;} 堆 完全二叉树 数组存储 大根堆 小根堆 空间利用率高 索引计算快

三、堆的核心操作:上下调整

操作复杂度对比

操作 时间复杂度 空间复杂度 说明 插入(offer) O(logN) O(1) 需要向上调整(shiftUp) 删除(poll) O(logN) O(1) 需要向下调整(shiftDown) 查看(peek) O(1) O(1) 直接返回堆顶元素 建堆 O(N) O(1) 自底向上调整比逐个插入更高效
// 向下调整示例(小根堆)void shiftDown(int[] arr, int parent, int len) { int child = 2*parent + 1; while (child < len) { // 找出较小的孩子 if (child+1 < len && arr[child+1] < arr[child]) child++; // 如果父节点已经比孩子小,调整结束 if (arr[parent] <= arr[child]) break; swap(arr, parent, child); // 交换父子 parent = child; // 继续向下调整 child = 2*parent + 1; }}

四、堆排序 vs 快速排序

特性 堆排序 快速排序 时间复杂度 O(NlogN) O(NlogN)平均 空间复杂度 O(1) O(logN)递归栈 稳定性 不稳定 不稳定 最坏情况 O(NlogN) O(N²) 数据访问模式 跳跃访问(缓存不友好) 顺序访问(缓存友好) 适用场景 大数据量 中小数据量

#mermaid-svg-5V0xp62OAtTwO3td {font-family:\"trebuchet ms\",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-5V0xp62OAtTwO3td .error-icon{fill:#552222;}#mermaid-svg-5V0xp62OAtTwO3td .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-5V0xp62OAtTwO3td .edge-thickness-normal{stroke-width:2px;}#mermaid-svg-5V0xp62OAtTwO3td .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-5V0xp62OAtTwO3td .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-5V0xp62OAtTwO3td .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-5V0xp62OAtTwO3td .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-5V0xp62OAtTwO3td .marker{fill:#333333;stroke:#333333;}#mermaid-svg-5V0xp62OAtTwO3td .marker.cross{stroke:#333333;}#mermaid-svg-5V0xp62OAtTwO3td svg{font-family:\"trebuchet ms\",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-5V0xp62OAtTwO3td .label{font-family:\"trebuchet ms\",verdana,arial,sans-serif;color:#333;}#mermaid-svg-5V0xp62OAtTwO3td .cluster-label text{fill:#333;}#mermaid-svg-5V0xp62OAtTwO3td .cluster-label span{color:#333;}#mermaid-svg-5V0xp62OAtTwO3td .label text,#mermaid-svg-5V0xp62OAtTwO3td span{fill:#333;color:#333;}#mermaid-svg-5V0xp62OAtTwO3td .node rect,#mermaid-svg-5V0xp62OAtTwO3td .node circle,#mermaid-svg-5V0xp62OAtTwO3td .node ellipse,#mermaid-svg-5V0xp62OAtTwO3td .node polygon,#mermaid-svg-5V0xp62OAtTwO3td .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-5V0xp62OAtTwO3td .node .label{text-align:center;}#mermaid-svg-5V0xp62OAtTwO3td .node.clickable{cursor:pointer;}#mermaid-svg-5V0xp62OAtTwO3td .arrowheadPath{fill:#333333;}#mermaid-svg-5V0xp62OAtTwO3td .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-5V0xp62OAtTwO3td .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-5V0xp62OAtTwO3td .edgeLabel{background-color:#e8e8e8;text-align:center;}#mermaid-svg-5V0xp62OAtTwO3td .edgeLabel rect{opacity:0.5;background-color:#e8e8e8;fill:#e8e8e8;}#mermaid-svg-5V0xp62OAtTwO3td .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-5V0xp62OAtTwO3td .cluster text{fill:#333;}#mermaid-svg-5V0xp62OAtTwO3td .cluster span{color:#333;}#mermaid-svg-5V0xp62OAtTwO3td div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\"trebuchet ms\",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-5V0xp62OAtTwO3td :root{--mermaid-font-family:\"trebuchet ms\",verdana,arial,sans-serif;} 排序算法 比较排序 堆排序 快速排序 原地排序 不稳定 分治思想 平均更快

五、PriorityQueue使用指南

构造方法对比

构造方法 说明 new PriorityQueue() 默认容量11,自然排序 new PriorityQueue(int capacity) 指定初始容量 new PriorityQueue(Comparator) 自定义比较器(可实现大根堆) new PriorityQueue(Collection) 用已有集合初始化(自动建堆)
// 大根堆实现PriorityQueue<Integer> maxHeap = new PriorityQueue<>((a,b) -> b-a);// 自定义对象排序PriorityQueue<Student> pq = new PriorityQueue<>( (s1, s2) -> s1.score != s2.score ? s2.score - s1.score : // 分数高的在前 s1.name.compareTo(s2.name) // 分数相同按名字);

六、TopK问题的三种解法对比

方法 时间复杂度 空间复杂度 适用场景 快速排序+取前K O(NlogN) O(logN) 数据可全部装入内存 堆排序 O(NlogK) O(K) 海量数据,K较小 冒泡K次 O(N*K) O(1) K非常小(如K=1,2)

#mermaid-svg-cmYpWZw0HkMW8Fz4 {font-family:\"trebuchet ms\",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-cmYpWZw0HkMW8Fz4 .error-icon{fill:#552222;}#mermaid-svg-cmYpWZw0HkMW8Fz4 .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-cmYpWZw0HkMW8Fz4 .edge-thickness-normal{stroke-width:2px;}#mermaid-svg-cmYpWZw0HkMW8Fz4 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-cmYpWZw0HkMW8Fz4 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-cmYpWZw0HkMW8Fz4 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-cmYpWZw0HkMW8Fz4 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-cmYpWZw0HkMW8Fz4 .marker{fill:#333333;stroke:#333333;}#mermaid-svg-cmYpWZw0HkMW8Fz4 .marker.cross{stroke:#333333;}#mermaid-svg-cmYpWZw0HkMW8Fz4 svg{font-family:\"trebuchet ms\",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-cmYpWZw0HkMW8Fz4 .label{font-family:\"trebuchet ms\",verdana,arial,sans-serif;color:#333;}#mermaid-svg-cmYpWZw0HkMW8Fz4 .cluster-label text{fill:#333;}#mermaid-svg-cmYpWZw0HkMW8Fz4 .cluster-label span{color:#333;}#mermaid-svg-cmYpWZw0HkMW8Fz4 .label text,#mermaid-svg-cmYpWZw0HkMW8Fz4 span{fill:#333;color:#333;}#mermaid-svg-cmYpWZw0HkMW8Fz4 .node rect,#mermaid-svg-cmYpWZw0HkMW8Fz4 .node circle,#mermaid-svg-cmYpWZw0HkMW8Fz4 .node ellipse,#mermaid-svg-cmYpWZw0HkMW8Fz4 .node polygon,#mermaid-svg-cmYpWZw0HkMW8Fz4 .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-cmYpWZw0HkMW8Fz4 .node .label{text-align:center;}#mermaid-svg-cmYpWZw0HkMW8Fz4 .node.clickable{cursor:pointer;}#mermaid-svg-cmYpWZw0HkMW8Fz4 .arrowheadPath{fill:#333333;}#mermaid-svg-cmYpWZw0HkMW8Fz4 .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-cmYpWZw0HkMW8Fz4 .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-cmYpWZw0HkMW8Fz4 .edgeLabel{background-color:#e8e8e8;text-align:center;}#mermaid-svg-cmYpWZw0HkMW8Fz4 .edgeLabel rect{opacity:0.5;background-color:#e8e8e8;fill:#e8e8e8;}#mermaid-svg-cmYpWZw0HkMW8Fz4 .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-cmYpWZw0HkMW8Fz4 .cluster text{fill:#333;}#mermaid-svg-cmYpWZw0HkMW8Fz4 .cluster span{color:#333;}#mermaid-svg-cmYpWZw0HkMW8Fz4 div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\"trebuchet ms\",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-cmYpWZw0HkMW8Fz4 :root{--mermaid-font-family:\"trebuchet ms\",verdana,arial,sans-serif;} TopK问题 排序法 堆方法 分治法 全排序后取前K 维护大小为K的堆 类似快速选择 小根堆求最大K 大根堆求最小K

七、堆的常见面试题

1. 堆的建立过程(以小根堆为例)

//向下调整方法(复杂度logN) public static void shiftDown(int[] array, int index){ //要调整的父节点 int parent = index; //要调整的孩子节点 int child = 2*parent + 1; while (child < array.length){ //child+1其实代表的是右子树 //判断左右子树大小 if(child+1<array.length && array[child+1] < array[child]){ //左右子树对调 child = child+1; } //判断左子树和父节点的大小 if (array[child] >= array[parent]){ break; } else{ int temp = array[parent]; array[parent] = array[child]; array[child] = temp; //更新父节点和子节点的指向 parent = child; child = 2*parent +1; } } } /** *建堆操作复杂度O(n) * @param array */ public static void createHeap(int[] array){ //要先找到最后一个非叶子节点 int lastLeaf = array.length-1; int lastParent = (lastLeaf-1)/2; for (int i = lastParent; i >= 0; i--){ shiftDown(array, i); } }

2. 堆的应用场景总结

应用场景 使用的堆类型 原因说明 堆排序 大根堆/小根堆 升序用大根堆,降序用小根堆 TopK最大元素 小根堆 维护K个元素的小根堆,淘汰小的 TopK最小元素 大根堆 维护K个元素的大根堆,淘汰大的 任务调度(优先级高的先执行) 大根堆 优先级高的在堆顶 合并K个有序链表 小根堆 每次取最小节点,效率O(logK) Dijkstra算法 小根堆 每次取距离最小的节点

八、总结:堆的\"堆\"德

堆的优缺点分析

优点:

  1. 插入/删除时间复杂度稳定在O(logN)
  2. 获取极值(堆顶)只需O(1)
  3. 可以高效解决TopK问题
  4. 堆排序是原地排序,空间复杂度O(1)

缺点:

  1. 访问非堆顶元素效率低(需要遍历)
  2. 不是稳定排序(相同元素可能换位)
  3. 缓存不友好(数组跳跃访问)

#mermaid-svg-Xz1KQHZk15kuUiq8 {font-family:\"trebuchet ms\",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-Xz1KQHZk15kuUiq8 .error-icon{fill:#552222;}#mermaid-svg-Xz1KQHZk15kuUiq8 .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-Xz1KQHZk15kuUiq8 .edge-thickness-normal{stroke-width:2px;}#mermaid-svg-Xz1KQHZk15kuUiq8 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-Xz1KQHZk15kuUiq8 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-Xz1KQHZk15kuUiq8 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-Xz1KQHZk15kuUiq8 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-Xz1KQHZk15kuUiq8 .marker{fill:#333333;stroke:#333333;}#mermaid-svg-Xz1KQHZk15kuUiq8 .marker.cross{stroke:#333333;}#mermaid-svg-Xz1KQHZk15kuUiq8 svg{font-family:\"trebuchet ms\",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-Xz1KQHZk15kuUiq8 .label{font-family:\"trebuchet ms\",verdana,arial,sans-serif;color:#333;}#mermaid-svg-Xz1KQHZk15kuUiq8 .cluster-label text{fill:#333;}#mermaid-svg-Xz1KQHZk15kuUiq8 .cluster-label span{color:#333;}#mermaid-svg-Xz1KQHZk15kuUiq8 .label text,#mermaid-svg-Xz1KQHZk15kuUiq8 span{fill:#333;color:#333;}#mermaid-svg-Xz1KQHZk15kuUiq8 .node rect,#mermaid-svg-Xz1KQHZk15kuUiq8 .node circle,#mermaid-svg-Xz1KQHZk15kuUiq8 .node ellipse,#mermaid-svg-Xz1KQHZk15kuUiq8 .node polygon,#mermaid-svg-Xz1KQHZk15kuUiq8 .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-Xz1KQHZk15kuUiq8 .node .label{text-align:center;}#mermaid-svg-Xz1KQHZk15kuUiq8 .node.clickable{cursor:pointer;}#mermaid-svg-Xz1KQHZk15kuUiq8 .arrowheadPath{fill:#333333;}#mermaid-svg-Xz1KQHZk15kuUiq8 .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-Xz1KQHZk15kuUiq8 .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-Xz1KQHZk15kuUiq8 .edgeLabel{background-color:#e8e8e8;text-align:center;}#mermaid-svg-Xz1KQHZk15kuUiq8 .edgeLabel rect{opacity:0.5;background-color:#e8e8e8;fill:#e8e8e8;}#mermaid-svg-Xz1KQHZk15kuUiq8 .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-Xz1KQHZk15kuUiq8 .cluster text{fill:#333;}#mermaid-svg-Xz1KQHZk15kuUiq8 .cluster span{color:#333;}#mermaid-svg-Xz1KQHZk15kuUiq8 div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\"trebuchet ms\",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-Xz1KQHZk15kuUiq8 :root{--mermaid-font-family:\"trebuchet ms\",verdana,arial,sans-serif;} 堆的优点 高效插入删除 快速获取极值 解决TopK 原地排序 堆的缺点 非随机访问 不稳定 缓存不友好

九、终极对比表:堆 vs 其他数据结构

特性 堆 二叉搜索树 跳表 哈希表 查找极值 O(1) O(logN) O(logN) O(N) 插入/删除 O(logN) O(logN) O(logN) O(1)平均 有序性 部分有序(仅堆顶) 完全有序 完全有序 无序 空间复杂度 O(N) O(N) O(N) O(N) 实现难度 中等 中等 困难 中等 典型应用 优先级队列、TopK 范围查询、有序数据 高性能有序数据结构 快速查找、去重

最后的小幽默

程序员的世界里:

  • 当你学会堆:哇!我\"堆\"数据结构理解好深!
  • 当你写堆代码:这bug怎么\"堆\"了这么多!
  • 当你面试被问堆:面试官,咱们能\"堆\"心一点吗?

在这里插入图片描述