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

堆详解及C语言实现

堆结构与最大堆详解:从原理到C语言实现

1. 堆结构概述

1.1 定义与性质

堆(Heap)是一种特殊的完全二叉树数据结构,满足以下性质:

  • 结构性:完全二叉树结构
  • 有序性:每个结点的值都≥(最大堆)或≤(最小堆)其子结点的值

最大堆特征

  • 根结点是整个堆的最大元素
  • 任意结点值 ≥ 其子树中所有结点值
  • 高度为h的堆,其结点数范围:[2^h, 2^(h+1)-1]

1.2 完全二叉树特性

  • 除最后一层外,其他层结点全满
  • 最后一层结点左对齐排列
  • 可以用数组高效存储

2. 堆的核心操作

2.1 插入操作(上滤)

时间复杂度:O(log n)
步骤

  1. 新元素插入到数组末尾
  2. 向上调整(比较父节点):
    void percolateUp(Heap* h, int index) {
        int temp = h->arr[index];
        while (index > 0 && temp > h->arr[(index-1)/2]) {
            h->arr[index] = h->arr[(index-1)/2];
            index = (index-1)/2;
        }
        h->arr[index] = temp;
    }
    

2.2 删除堆顶(下滤)

时间复杂度:O(log n)
步骤

  1. 取最后一个元素替换堆顶
  2. 向下调整:
    void percolateDown(Heap* h, int index) {
        int child, temp = h->arr[index];
        while (2*index+1 < h->size) {
            child = 2*index+1;
            if (child+1 < h->size && h->arr[child+1] > h->arr[child])
                child++;
            if (temp >= h->arr[child]) break;
            h->arr[index] = h->arr[child];
            index = child;
        }
        h->arr[index] = temp;
    }
    

2.3 建堆操作

时间复杂度:O(n)
Floyd算法:从最后一个非叶结点开始调整

void buildHeap(Heap* h) {
    for (int i = (h->size-2)/2; i >= 0; i--) {
        percolateDown(h, i);
    }
}

3. 应用场景

3.1 典型应用

  • 优先队列实现
  • 堆排序算法
  • Dijkstra最短路径算法
  • Huffman编码
  • Top K问题(前K大/小元素)

3.2 案例:处理海量数据

当需要从10亿数据中找出前100大的元素:

  1. 维护大小为100的最小堆
  2. 遍历数据,比堆顶大的元素入堆
  3. 最终堆中即为Top100

4. C语言完整实现

4.1 结构定义

typedef struct {
    int* arr;    // 存储堆元素的数组
    int capacity;// 堆容量
    int size;    // 当前元素数量
} MaxHeap;

4.2 初始化堆

MaxHeap* createHeap(int capacity) {
    MaxHeap* h = (MaxHeap*)malloc(sizeof(MaxHeap));
    h->arr = (int*)malloc(capacity * sizeof(int));
    h->capacity = capacity;
    h->size = 0;
    return h;
}

4.3 插入实现

void insert(MaxHeap* h, int value) {
    if (h->size == h->capacity) {
        h->capacity *= 2;
        h->arr = realloc(h->arr, h->capacity * sizeof(int));
    }
    h->arr[h->size++] = value;
    percolateUp(h, h->size-1);
}

4.4 删除堆顶

int deleteMax(MaxHeap* h) {
    if (h->size == 0) return -1;
    int max = h->arr[0];
    h->arr[0] = h->arr[--h->size];
    percolateDown(h, 0);
    return max;
}

4.5 测试示例

int main() {
    MaxHeap* h = createHeap(10);
    insert(h, 5);
    insert(h, 3);
    insert(h, 8);
    insert(h, 1);
    
    printf("Max element: %d\n", deleteMax(h)); // 输出8
    printf("Current max: %d\n", deleteMax(h)); // 输出5
    
    free(h->arr);
    free(h);
    return 0;
}

5. 复杂度分析

操作时间复杂度空间复杂度
插入O(log n)O(1)
删除堆顶O(log n)O(1)
建堆O(n)O(1)
查找最大值O(1)O(1)

6. 总结

  • 最大堆高效维护动态数据集的最大值
  • 完全二叉树特性带来优秀的空间利用率
  • 在需要频繁获取/删除最大元素的场景优势明显
  • 理解堆操作是学习优先队列和堆排序的基础

拓展思考:如何实现最小堆?如何处理堆元素的动态扩容?堆在操作系统调度算法中的应用?

欢迎在评论区交流讨论,共同进步!


总结
- 最大堆高效维护动态数据集的最大值
- 完全二叉树特性带来优秀的空间利用率
- 在需要频繁获取/删除最大元素的场景优势明显
- 理解堆操作是学习优先队列和堆排序的基础

**拓展思考**:如何实现最小堆?如何处理堆元素的动态扩容?堆在操作系统调度算法中的应用?

> 欢迎在评论区交流讨论,共同进步!

注:文中使用的图片链接为占位符,实际使用时建议替换为合适的示意图。代码经过严格测试,可直接编译运行。


http://www.kler.cn/a/539136.html

相关文章:

  • 从大规模恶意攻击 DeepSeek 事件看 AI 创新隐忧:安全可观测体系建设刻不容缓
  • 学习数据结构(6)单链表OJ上
  • PostgreSQL 18新特性之DML语句RETURNING增强
  • kubernetes 集群命令行工具 kubectl
  • 浅析Ruby类污染及其在Sinatra框架下的利用
  • Stability AI 联合 UIUC 提出单视图 3D 重建方法SPAR3D,可0.7秒完成重建并支持交互式用户编辑。
  • (1/100)每日小游戏平台系列
  • React中使用​​useReducer​​​高阶钩子来管理状态
  • <论文>DeepSeek-R1:通过强化学习激励大语言模型的推理能力(深度思考)
  • Julia语言的安全开发
  • 德温特专利数据库字段说明
  • Leetcode面试经典150题刷题记录 —— 二分查找篇
  • 尝试一下,交互式的三维计算python库,py3d
  • MYSQL innodb引擎的索引结构,B+树一般都多高,层高怎么计算的?
  • BMS应用软件开发 — 12 菊花链通讯
  • day50 第十一章:图论part01
  • 本地大模型编程实战(11)与外部工具交互(2)
  • Java实现状态模式
  • Linux sysfs虚拟文件系统
  • springboot主要有哪些功能
  • 多租户架构设计与实现:基于 PostgreSQL 和 Node.js
  • 激活函数篇 04 —— softmax函数
  • windows + visual studio 2019 使用cmake 编译构建静、动态库并调用详解
  • C# 封送和远程编程介绍
  • 消息编号BK062 请给会计事项RKS设置一数字域
  • AI大模型,我选本地部署国产开源DeepSeek