堆和堆排序

1 引言

堆(Heap)本质上是一种基于数组实现的完全二叉树。它通过严格的父子节点大小约束,保证能在 O(1) 的时间内获取极值。在底层原理与系统设计中,堆既是高效的优先队列,也是操作系统调度的核心基石。

2 基本概念

2.1 数据机构

从数据结构上看,它本质上就是一个数组。```c

1, 3, 2, 7, 5, 8, 4

复制代码
模拟的树结构:

```c
          1
        /   \
       3     2
      / \   / \
     7   5 8   4

2.2 结构性

它必须是一棵完全二叉树:除最后一层外,其余各层节点全部填满,且最后一层的节点靠左排列。

大顶堆 :任意节点的值 ≥ 其子节点的值(根节点最大)。

小顶堆:任意节点的值 ≤ 其子节点的值(根节点最小)。

正因为是完全二叉树,每个节点都可以直接映射到数组下标。假设当前节点的数组下标为 i,则:

  • 其父节点下标:(i - 1) / 2
  • 其左子节点下标:2 * i + 1
  • 其右子节点下标:2 * i + 2## 3 操作

3 建堆

3.1 步骤

大顶堆:

以大顶堆为例:

  1. 建立数组 arr[N],用于存储原始数据。
  2. 找到最后一个叶子节点,即 arr[N-1]。
  3. 找到从后往前的第一个非叶子节点,即最后一个节点的父节点:((N-1) - 1) / 2 = m。
  4. 从下标 m 开始,对每个非叶子节点执行下沉操作:
    (1)将父节点 m 与其子节点 2*m + 1、2*m + 2 比较,若父节点小于子节点的最大者,则交换两者位置;
    (2)若在(1)中 m 与 2*m + 1 发生了交换,则继续对 2*m + 1 执行步骤(1)。
  5. 依次对下标 m-1, m-2, ... 0 按步骤 4 处理。

3.2 举例

c 复制代码
        4
      /   \
    10     3
   / \    / \
  5   1  8   7
  1. 建数组[4, 10, 3, 5, 1, 8, 7]

  2. 找到最后一个叶子节点,最后一个叶子节点为7,对应下标为6

  3. 找到第一个非叶子节点,计算公式:(6-1)/2 = 2

  4. 下标2数值是3,其子节点下标为5,6,数值分别是8,7

    (1)3 < 8,交换两者位置:[4, 10, 8, 5, 1, 3, 7],3无子节点不用继续计算

  5. 下标1数值是10,其子节点下标为3,4,数值分别是5,1

    (1) 5 < 10,无需交换

  6. 下标0数值是4,其子节点下标为1,2,数值分别是10,8

    (1)4 < 10,交换两者位置:[10, 4, 8, 5, 1, 3, 7]

    (2)发生了交换,继续对4做下沉。

    (3)4 < 5,交换两者位置:[10, 5, 8, 4, 1, 3, 7]

    (4)发生了交换,继续对4做下沉,4是叶子节点无需再进行

大顶堆建好:

c 复制代码
        10
      /    \
     5      8
    / \    / \
   4   1  3   7

4 堆排序

堆排序就是把数组原地看成一个大顶堆,反复把堆顶最大值换到数组末尾,从而完成排序。

大顶堆为例:

  1. 建堆
  2. 交换堆顶和末尾:将当前最大数据放到后面
  3. 对剩余元素重新建堆
  4. 重复2和3步骤

5 插入和删除

5.1 步骤

  • 插入(上浮):将新元素放到数组末尾,然后不断与父节点比较。如果违背了堆序性(比如小顶堆中比父节点小),就交换位置,直到满足条件。
  • 删除堆顶(下沉):将数组末尾元素移到堆顶,然后不断与较小的子节点(小顶堆)比较并交换,直到沉到合适的位置。

6 时间复杂度

操作 时间复杂度 说明
查询堆顶 O(1) 直接取根节点,最大/最小值
插入 O(log n) 放到末尾后上浮
删除堆顶 O(log n) 末尾元素换到堆顶后下沉
建堆 O(n) 自底向下调整建堆
堆排序 O(n log n) 建堆 O(n) + n 次删除堆顶,每次 O(log n)

关于建堆的时间复杂度:

完全二叉树里,越底层的节点越多,但它们能下沉的距离越短,且非叶子节点只有n/2个,

最终计算下来时间复杂度能收敛在O(n)级别。

相关推荐
TK泰妞1 小时前
TikTok 带货视频如何做多语言本地化?从翻译脚本到重做场景的实用方法
算法·音视频
房开民1 小时前
DDPM 完整原理 + 全套公式串联
算法
lunar_coder1 小时前
哈希扩展 -- 位图思想
c++·算法·哈希算法
秋天的怀念_David1 小时前
听故事学语言 · 数据结构篇 · 序章一 算法之问
数据结构·程序人生·算法
LG.YDX1 小时前
基于中心的3D目标检测和探索追踪-笔记
笔记·算法·目标检测
民乐团扒谱机1 小时前
【读论文】音色在微分音程记忆中的作用
人工智能·深度学习·算法
Navigator_Z1 小时前
LeetCode //C - 1306. Jump Game III
c语言·算法·leetcode
小O的算法实验室2 小时前
IEEE TASE,面向无人机的不确定性感知信息路径规划:可解释贝叶斯强化学习方法
算法
L0208242 小时前
Kubernetes Service 与 kube‑proxy 深度详解
运维·算法·云原生·容器·贪心算法·kubernetes