算法基础 -- 小根堆构建的两种方式:上浮法与下沉法

小根堆构建的两种方式:上浮法与下沉法

在构建小根堆(Min-Heap)时,通常有两种常见的构建方式:

  1. 上浮建堆(逐个插入,上浮调整)
  2. 下沉建堆(Heapify 自底向上,下沉调整)

这两种方法在时间复杂度上有显著差异。


一、上浮建小根堆:逐个插入 + 上浮调整

1. 核心原理:

  • 对于给定的无序数组,逐个插入到堆中。

  • 每次插入新元素时,将其放在堆的最后一个位置(末尾),然后执行"上浮"调整:

    • 将新元素与其父节点比较,如果新元素更小,则与父节点交换。
    • 重复此过程,直到新元素达到正确的位置或成为堆顶。

2. 上浮过程示例:

  • 对于每个新插入的元素,最多需要调整至堆顶。
  • 在完全二叉树中,高度为 ⌊ log ⁡ n ⌋ \lfloor \log n \rfloor ⌊logn⌋。
  • 因此,单个元素上浮的时间复杂度为 O ( log ⁡ n ) O(\log n) O(logn)。

3. 总体时间复杂度分析:

  • 对于 n n n 个元素,逐个插入,每次上浮调整:

    O ( 1 × log ⁡ 1 ) + O ( 1 × log ⁡ 2 ) + ⋯ + O ( 1 × log ⁡ n ) O(1 \times \log 1) + O(1 \times \log 2) + \cdots + O(1 \times \log n) O(1×log1)+O(1×log2)+⋯+O(1×logn)

  • 这相当于一个对数级数求和:

    ∑ i = 1 n log ⁡ i ≈ O ( n log ⁡ n ) \sum_{i=1}^{n} \log i \approx O(n \log n) i=1∑nlogi≈O(nlogn)

  • 结论:上浮建堆的时间复杂度为 O ( n log ⁡ n ) O(n \log n) O(nlogn)


二、下沉建小根堆:Heapify 自底向上

1. 核心原理:

  • 直接将无序数组视为一个完全二叉树。

  • 从最后一个非叶子节点开始,逐个向前进行"下沉"调整:

    • 对当前节点执行下沉:

      • 与左右子节点中较小的一个交换,确保当前节点保持小根堆性质。
    • 重复下沉,直到当前节点满足堆性质或成为叶节点。

2. 下沉过程示例:

  • 对于每个非叶子节点进行下沉操作。

  • 下沉操作的时间取决于树的高度:

    • 对于完全二叉树,树高为 ⌊ log ⁡ n ⌋ \lfloor \log n \rfloor ⌊logn⌋。

    • 但下沉的层次是逐级减少的:

      • n / 2 n/2 n/2 个节点(叶节点)不需要下沉。
      • n / 4 n/4 n/4 个节点下沉 1 次。
      • n / 8 n/8 n/8 个节点下沉 2 次。
      • ......

3. 总体时间复杂度分析:

  • 这是一种渐进减半的过程

    ∑ i = 1 log ⁡ n n 2 i × i \sum_{i=1}^{\log n} \frac{n}{2^i} \times i i=1∑logn2in×i

  • 该求和公式的复杂度为 O ( n ) O(n) O(n),这是因为下沉过程中的递减效果:

T ( n ) = 2 × n 2 × 1 + 2 × n 4 × 2 + 2 × n 8 × 3 + ⋯ ≈ O ( n ) T(n) = 2 \times \frac{n}{2} \times 1 + 2 \times \frac{n}{4} \times 2 + 2 \times \frac{n}{8} \times 3 + \cdots \approx O(n) T(n)=2×2n×1+2×4n×2+2×8n×3+⋯≈O(n)

  • 结论:下沉建堆的时间复杂度为 O ( n ) O(n) O(n)

三、两种建堆方式的时间复杂度对比

建堆方式 上浮建堆(逐个插入) 下沉建堆(Heapify)
原理 逐个插入,上浮调整 自底向上,下沉调整
调整过程 每次上浮至正确位置 从最后一个非叶节点下沉
复杂度 O ( n log ⁡ n ) O(n \log n) O(nlogn) O ( n ) O(n) O(n)

四、为什么下沉建堆更高效?

  • 下沉建堆(Heapify)直接从中间节点开始调整,避免了对叶子节点的重复操作。
  • 叶子节点天生满足堆的性质,因此可以忽略。
  • 而上浮建堆在每次插入时都进行上浮,无法利用已经部分有序的特性,导致较高的复杂度。

五、实际应用中的选择:

  • 上浮建堆: 常用于动态增量插入堆的情况(如优先队列逐个入队)。
  • 下沉建堆: 常用于一次性构建堆(如堆排序)。
相关推荐
牛客企业服务39 分钟前
2025年AI面试推荐榜单,数字化招聘转型优选
人工智能·python·算法·面试·职场和发展·金融·求职招聘
糖葫芦君1 小时前
Policy Gradient【强化学习的数学原理】
算法
向阳@向远方3 小时前
第二章 简单程序设计
开发语言·c++·算法
github_czy4 小时前
RRF (Reciprocal Rank Fusion) 排序算法详解
算法·排序算法
许愿与你永世安宁4 小时前
力扣343 整数拆分
数据结构·算法·leetcode
爱coding的橙子4 小时前
每日算法刷题Day42 7.5:leetcode前缀和3道题,用时2h
算法·leetcode·职场和发展
满分观察网友z5 小时前
从一次手滑,我洞悉了用户输入的所有可能性(3330. 找到初始输入字符串 I)
算法
YuTaoShao5 小时前
【LeetCode 热题 100】73. 矩阵置零——(解法二)空间复杂度 O(1)
java·算法·leetcode·矩阵
Heartoxx5 小时前
c语言-指针(数组)练习2
c语言·数据结构·算法
大熊背6 小时前
图像处理专业书籍以及网络资源总结
人工智能·算法·microsoft