最小堆数据结构

最小堆实现提供了一种高效的数据结构,用于管理动态变化的元素列表,同时支持快速取出最小值。它是一种满足堆性质的树形数据结构,支持插入、删除和弹出最小元素等常见操作。

本节介绍该实现的设计动机、内部结构、API 用法,以及嵌入式系统和实时环境中的应用场景。

堆结构

堆以存储在数组中的完全二叉树形式维护。每个节点都满足 最小堆 性质:

  • 每个节点的值都小于或等于其子节点的值。

这一性质确保 最小元素始终位于根节点 (索引 0)。

Index:      0   1   2   3   4   5   6
Values:    [1,  3,  5,  8,  9, 10, 12]

               1
             /   \
           3       5
          / \     / \
         8   9  10  12

对于索引为 i 的节点,其子节点的索引为:

  • 左子节点:\(2*i + 1\)

  • 右子节点:\(2*i + 2\)

其父节点的索引为:

  • 父节点:\((i - 1) / 2\)

使用场景

最小堆适用于:

  • 实现优先级队列

  • 增量排序数据

  • 资源仲裁(例如选择成本最低的资源)

  • 协作式多任务系统中的调度

  • 管理超时和延迟队列

  • 基于优先级的传感器采样或数据采样

在 Zephyr 等 RTOS 环境中,内核级或应用级模块需要以尽可能低的延迟获取最高优先级资源时,可以使用此堆。

值版本与引用版本

实现提供两个版本,仅元素存储方式不同:

  • min_heap (如上所述)在连续缓冲区中 按值 存储元素。可按内容搜索或按索引删除任意元素,适用于存储小型值并按内容查找的优先级队列。

  • min_heap_ref 存储指向调用者所拥有节点的 引用,每个节点嵌入一个 min_heap_handle。插入操作无需复制;利用调用者已持有的句柄,可以在 \(O(\log n)\) 时间内删除指定节点,无需搜索。它适用于按对象身份而非内容删除的长生命周期对象,例如内核超时对象。

两者互为补充:值堆按对象身份删除的复杂度无法优于 \(O(n)\),而引用堆不适合按值存储并搜索的用法。min_heap_ref 完全由头文件实现,无需 Kconfig 配置。

示例

Min-Heap Data Structure 示例演示了 Zephyr RTOS 中最小堆实现的 API 用法。

API 参考

值堆

Min-heap

引用堆

Reference min-heap