前端会用到的数据结构--堆(HEAP)

堆是什么?

  1. 完全二叉树

    1. 除最后一层外,每层都填满
    2. 用数组存储非常高效,父子节点下标有规律
  2. 堆顶始终是最大或最小的数,便于快速取出。

应用场景

1️⃣ 堆排序(Heap Sort)

原理:构建一个最大堆,每次取堆顶元素(最大),放到数组末尾,重复堆化。

时间复杂度:O(n log k)

📌 应用:

  • 在一万条数据里,取最大的10个数
  • React 内部 reconciler 中有对 fiber list 的优先级调整过程(虽然更复杂)

2️⃣ React 的 scheduler 中的最小堆队列

React 17+ 中的 scheduler 模块用于调度更新任务,其核心是一个时间驱动的优先级队列

源码地址:

arduino 复制代码
js
复制编辑
const taskQueue = new HeapQueue();   // 按照 expirationTime 排序(时间优先)
const timerQueue = new HeapQueue();  // 按照 startTime 排序(定时任务)

这里使用的是 最小堆,以保证:

  • 取出最早过期或最早开始的任务是 O(1)
  • 插入/更新任务是 O(log n)

📌 相关概念:

  • expirationTime 决定任务的紧急程度(Lanes机制)
  • startTime 控制任务延迟开始(如 setTimeout

3️⃣ 前端动画调度器(如 requestIdleCallback polyfill)

浏览器的 requestIdleCallback 用于在浏览器空闲时间运行回调,类似的调度器内部也常用最小堆存储任务(按照预定的执行时间排序),例如:

yaml 复制代码
js
复制编辑
[
  { callback: fn1, time: 158000001 },
  { callback: fn2, time: 158000003 }
]

每一帧取出堆顶执行任务(即将过期的),其余任务继续等待。


4️⃣ 优先级任务队列 / 限流工具

你实现一个并发请求池(如 5 并发),但需要支持优先级调度,可用最大堆实现优先级队列:

javascript 复制代码
js
复制编辑
class Task {
  constructor(priority, callback) { ... }
}

堆顶是优先级最高的任务,先执行它。

📌 应用:

  • 文件上传任务队列(优先级)
  • 渲染任务(长列表懒加载)

5️⃣ 前端游戏 / 动画帧控制系统

在复杂的 WebGL、canvas 动画或游戏循环中,需要按执行时间调度任务帧 ------ 最小堆非常适合做这种"时间轴排序"。

例如:

scss 复制代码
js
复制编辑
scheduleAt(time, callback)

内部将任务按时间压入最小堆,当前帧时间到了就从堆顶拿任务执行。


为什么前端常用"最小堆"?

  • 因为前端调度大多数以**"时间驱动"或"优先级最小者先执行"**为主:

    • 比如:任务最早执行、超时最早发生、优先级最小者最紧急
  • 所以最小堆正好满足这个模型:堆顶是最小值,取用只要 O(1)


如何实现堆?

  • peek函数: 查看堆的顶点, 也就是优先级最高的tasktimer.
  • pop函数: 将堆的顶点提取出来, 并删除顶点之后, 需要调用siftDown函数向下调整堆.
  • push函数: 添加新节点, 添加之后, 需要调用siftUp函数向上调整堆.
  • siftDown函数: 向下调整堆结构, 保证数组是一个最小堆.
  • siftUp函数: 当插入节点之后, 需要向上调整堆结构, 保证数组是一个最小堆.

总结

面试官问:堆在前端有什么应用?
在前端开发中,堆主要应用在需要快速获取"最小/最大值"的任务调度场景中。例如:

  • React 中的 scheduler 模块使用最小堆管理任务队列,以 O(1) 获取优先级最高的任务
  • requestIdleCallback 的 polyfill 实现中,也会用最小堆安排任务执行时间
  • 自定义的并发任务队列(如上传、抓取)也可用最大堆做优先级控制
  • 当然,堆排序本身也可以用来实现稳定的 O(n log k) 排序

因为堆能在 log(n) 时间内插入任务,O(1) 获取最小值,所以非常适合调度类系统。

相关推荐
白瓷梅子汤2 分钟前
跟着官方示例学习 @tanStack-form --- Linked Fields
前端·react.js
爱学习的茄子6 分钟前
深入理解JavaScript闭包:从入门到精通的实战指南
前端·javascript·面试
zhanshuo37 分钟前
不依赖框架,如何用 JS 实现一个完整的前端路由系统
前端·javascript·html
火柴盒zhang38 分钟前
websheet在线电子表格(spreadsheet)在集团型企业财务报表中的应用
前端·html·报表·合并·spreadsheet·websheet·集团财务
khalil40 分钟前
基于 Vue3实现一款简历生成工具
前端·vue.js
拾光拾趣录1 小时前
浏览器对队头阻塞问题的深度优化策略
前端·浏览器
用户8122199367221 小时前
[已完结]后端开发必备高阶技能--自研企业级网关组件(Netty+Nacos+Disruptor)
前端
万少1 小时前
2025中了 聊一聊程序员为什么都要做自己的产品
前端·harmonyos
abigale033 小时前
webpack+vite前端构建工具 -11实战中的配置技巧
前端·webpack·node.js
专注API从业者3 小时前
构建淘宝评论监控系统:API 接口开发与实时数据采集教程
大数据·前端·数据库·oracle