当前位置: 首页 > news >正文

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

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

在构建小根堆(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=1nlogiO(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=1logn2in×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)直接从中间节点开始调整,避免了对叶子节点的重复操作。
  • 叶子节点天生满足堆的性质,因此可以忽略。
  • 而上浮建堆在每次插入时都进行上浮,无法利用已经部分有序的特性,导致较高的复杂度。

五、实际应用中的选择:

  • 上浮建堆: 常用于动态增量插入堆的情况(如优先队列逐个入队)。
  • 下沉建堆: 常用于一次性构建堆(如堆排序)。

相关文章:

  • 一款强大的压测带宽工具-iperf3
  • 容器编排利器-k8s入门指南
  • [AI算法] LLM训练-构建transformers custom model
  • 容器化-k8s-使用和部署
  • 前端面经 手写Promise
  • Linux 内核中 inet_accept 的实现与自定义传输协议优化
  • 部署docker上的redis,idea一直显示Failed to connect to any host resolved for DNS name
  • Tcping详细使用教程
  • .NET Core liunx二进制文件安装
  • 能源数字化转型关键引擎:Profinet转Modbus TCP网关驱动设备协同升级
  • 《k-means 散点图可视化》实验报告
  • 简单入门RabbitMQ
  • OrangePi Zero 3学习笔记(Android篇)11 - IR遥控器
  • python自学笔记2 数据类型
  • 汉诺塔超算堆栈结构编码和流程详细设计(附源代码)
  • [SpringBoot]Spring MVC(2.0)
  • Android native崩溃问题分析
  • Python基础:集合(Set)
  • 今日积累:若依框架配置QQ邮箱,来发邮件,注册账号使用
  • MySQL高可用
  • 小雨伞保险经纪母公司手回集团通过港交所聆讯
  • 俄乌官员即将在土耳其会谈,外交部:支持俄乌开启直接对话
  • 女孩患异食癖爱吃头发,一年后腹痛入院体内惊现“头发巨石”
  • 国台办:台湾自古属于中国,历史经纬清晰,法理事实清楚
  • 中巡组在行动丨①震慑:这些地区有官员落马
  • 明查|印度空军“又有一架战机被巴基斯坦击落,飞行员被俘”?