二叉堆(Binary Heap)的原理与操作
字数 1215 2025-12-04 22:00:38
二叉堆(Binary Heap)的原理与操作
二叉堆是一种特殊的完全二叉树,它满足堆属性:每个节点的值都大于等于(最大堆)或小于等于(最小堆)其子节点的值。这种结构常用于实现优先队列。
1. 二叉堆的结构特性
- 完全二叉树:除了最后一层,其他层节点全满,且最后一层节点靠左排列
- 堆属性:父节点值 ≥ 子节点值(最大堆)或父节点值 ≤ 子节点值(最小堆)
- 数组表示:利用完全二叉树特性,可以用数组紧凑存储(节省指针空间)
- 对于位置i的节点:
- 父节点:floor((i-1)/2)
- 左子节点:2i+1
- 右子节点:2i+2
- 对于位置i的节点:
2. 核心操作:上浮(Heapify Up)
当某个节点值大于其父节点时(最大堆),需要向上调整:
- 比较当前节点与父节点的值
- 如果违反堆属性,交换两者位置
- 重复过程直到满足堆属性或到达根节点
时间复杂度:O(log n),因为最多需要比较树的高度次
3. 核心操作:下沉(Heapify Down)
当某个节点值小于其子节点时(最大堆),需要向下调整:
- 比较当前节点与其左右子节点的值
- 找出值最大的子节点
- 如果子节点值大于当前节点,交换两者位置
- 重复过程直到满足堆属性或成为叶子节点
时间复杂度:O(log n)
4. 插入操作详细步骤
- 将新元素添加到堆的末尾(数组最后位置)
- 对新元素执行上浮操作:
- 比较新元素与其父节点的值
- 如果新元素值更大(最大堆),与父节点交换
- 重复此过程直到堆属性满足
- 示例:在最大堆[10,7,8,5,6]中插入9
- 添加后:[10,7,8,5,6,9]
- 比较9与其父节点8:9>8,交换→[10,7,9,5,6,8]
- 比较9与其父节点10:9<10,停止
5. 删除堆顶操作详细步骤
- 用最后一个元素替换堆顶元素
- 删除最后一个元素(原堆顶)
- 对新的堆顶元素执行下沉操作:
- 比较该元素与其左右子节点
- 与值更大的子节点交换
- 重复直到堆属性满足
- 示例:从最大堆[10,7,9,5,6,8]删除堆顶
- 用最后元素8替换堆顶:[8,7,9,5,6]
- 8与子节点比较:左7右9,9最大且9>8,交换→[9,7,8,5,6]
- 8与子节点比较:无子节点,停止
6. 建堆操作(Heap Construction)
从无序数组构建堆有两种方法:
- 自顶向下:重复调用插入操作,时间复杂度O(n log n)
- 自底向上:从最后一个非叶子节点开始向前遍历,对每个节点执行下沉操作
- 最后一个非叶子节点位置:floor(n/2)-1
- 时间复杂度:O(n),因为大部分节点在底层,下沉操作次数少
7. 堆排序原理
- 构建最大堆
- 重复以下步骤直到堆为空:
- 将堆顶元素(最大值)与最后一个元素交换
- 堆大小减1
- 对新的堆顶执行下沉操作
- 最终得到升序排列的数组
二叉堆通过巧妙利用完全二叉树的数组表示和简单的上浮/下沉操作,实现了高效的插入、删除和建堆操作,是优先队列和堆排序算法的基础数据结构。