数据结构初阶之堆的介绍与堆的实现

news2025/1/31 21:13:55

一、堆的概念与结构

如果有一个关键码的集合,把它的所有元素按完全二叉树的顺序存储在一个一维数组中,并满足:,则称为小堆(或大堆)。

根结点最大的堆叫做最大堆或大根堆根结点最小的堆叫做最小堆或小根堆

堆具有以下性质:

(1)堆中某个结点的值总是不大于或不小于其父结点的值;

(2)堆总是一棵完全二叉树。

二叉树的性质:

对于具有 n 个结点的完全二叉树,如果按照从上至下从左至右的数组顺序对所有结点从 0 开始编号,则对于序号为 i 的结点有:

(1)若 i > 0,i 位置结点的双亲序号:( i - 1 ) / 2 ;i = 0 时,i 为根结点编号,无双亲结点。

(2)若 2 * i + 1 < n,左孩子序号:2 * i + 1 。2 * i + 1 >= n 无左孩子。

(3)若 2 * i + 2 < n,右孩子序号:2 * i + 2 。2 * i + 2 >= n 无右孩子。

二、堆的实现

项目创建的时候,要创建一个头文件(.h)Heap.h ,两个源文件(.c)Heap.c ,test.c 。Heap.h 用于定义结构体和声明函数;Heap.c 用于实现函数;test.c 用于测试函数,每实现一个函数要进行相应的测试。编写代码过程中要勤测试,避免写出大量代码后再测试,如果出现问题,问题无从定位。

1、Heap.h

#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include<stdbool.h>

//定义堆的结构
typedef int DataType;
typedef struct Heap
{
    DataType* arr;
    int size;
    int capacity;
}Heap;

//对堆进行初始化
void Init_Heap(Heap* hp);

//判断堆是否为空
bool Empty_Heap(Heap* hp);

//销毁堆
void Destory_Heap(Heap* hp);

//打印堆
void Print_Heap(Heap* hp);

//交换数组中的两个元素
void Swap(int* x, int* y);

//向上调整算法,小堆
void Adjust_Up(DataType* arr, int child);

//入堆,往堆中增加数据
void Push_Heap(Heap* hp, DataType x);

//向下调整算法,小堆
void Adjust_Down(DataType* arr, int parent, int n);

//出堆,出的是堆顶的数据
void Pop_Heap(Heap* hp);

//取堆顶数据
DataType Get_Top_Heap(Heap* hp);

2、Heap.c

#include"Heap.h"

//对堆进行初始化
void Init_Heap(Heap* hp)
{
    assert(hp);
    hp->arr = NULL;
    hp->capacity = hp->size = 0;
}

//判断堆是否为空
bool Empty_Heap(Heap* hp)
{
    assert(hp);
    return hp->size == 0;
}

//销毁堆
void Destory_Heap(Heap* hp)
{
    assert(hp);
    if (hp->arr)
        free(hp->arr);
    hp->arr = NULL;
    hp->capacity = hp->size = 0;
}

//打印堆
void Print_Heap(Heap* hp)
{
    for (int i = 0; i < hp->size; i++)
    {
        printf("%d ", hp->arr[i]);
    }
    printf("\n");
}

//交换数组中的两个元素
void Swap(int* x, int* y)
{
    int tmp = *x;
    *x = *y;
    *y = tmp;
}

//向上调整算法,小堆
void Adjust_Up(DataType* arr, int child)
{
    int parent = (child - 1) / 2;
    while (child > 0)
    {
        if (arr[parent] > arr[child])
        {
            Swap(&arr[parent], &arr[child]);
            child = parent;
            parent = (child - 1) / 2;
        }
        else
            break;
    }
}

//向下调整算法,小堆
void Adjust_Down(DataType* arr, int parent, int n)
{
    int child = parent * 2 + 1;
    while (child < n)
    {
        if (child + 1 < n && arr[child] > arr[child + 1])
            child++;
        if (arr[parent] > arr[child])
        {
            Swap(&arr[parent], &arr[child]);
            parent = child;
            child = parent * 2 + 1;
        }
        else
            break;
    }
}

//入堆,往堆中增加数据
void Push_Heap(Heap* hp, DataType x)
{
    assert(hp);
    if (hp->capacity == hp->size)
    {
        int newcapacity = (hp->size == 0) ? 4 : 2 * hp->capacity;
        Heap* tmp = (Heap*)realloc(hp->arr, sizeof(newcapacity * sizeof(DataType)));
        if (!tmp)
        {
            perror("realloc fail!");
            exit(1);
        }
        hp->arr = tmp;
        hp->capacity = newcapacity;
    }
    hp->arr[hp->size] = x;
    Adjust_Up(hp->arr, hp->size);
    hp->size++;
}

//出堆,出的是堆顶的数据
void Pop_Heap(Heap* hp)
{
    assert(!Empty_Heap(hp));
    Swap(&hp->arr[0], &hp->arr[hp->size - 1]);
    hp->size--;
    Adjust_Down(hp->arr, 0, hp->size);
}

//取堆顶数据
DataType Get_Top_Heap(Heap* hp)
{
    assert(!Empty_Heap(hp));
    return hp->arr[0];
}
 

test.c自行测试,这里不予提供。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2288059.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Day29(补)-【AI思考】-精准突围策略——从“时间贫困“到“效率自由“的逆袭方案

文章目录 精准突围策略——从"时间贫困"到"效率自由"的逆袭方案**第一步&#xff1a;目标熵减工程&#xff08;建立四维坐标&#xff09;** 与其他学习方法的结合**第二步&#xff1a;清华方法本土化移植** 与其他工具对比**~~第三步&#xff1a;游戏化改造…

docker中运行的MySQL怎么修改密码

1&#xff0c;进入MySQL容器 docker exec -it 容器名 bash 我运行了 docker ps命令查看。正在运行的容器名称。可以看到MySQL的我起名为db docker exec -it db bash 这样就成功的进入到容器中了。 2&#xff0c;登录MySQL中 mysql -u 用户名 -p 回车 密码 mysql -u root -p roo…

leetcode——二叉树的中序遍历(java)

给定一个二叉树的根节点 root &#xff0c;返回 它的 中序 遍历 。 示例 1&#xff1a; 输入&#xff1a;root [1,null,2,3] 输出&#xff1a;[1,3,2] 示例 2&#xff1a; 输入&#xff1a;root [] 输出&#xff1a;[] 示例 3&#xff1a; 输入&#xff1a;root [1] 输出…

信息安全专业优秀毕业设计选题汇总:热点选题

目录 前言 毕设选题 开题指导建议 更多精选选题 选题帮助 最后 前言 大家好,这里是海浪学长毕设专题! 大四是整个大学期间最忙碌的时光&#xff0c;一边要忙着准备考研、考公、考教资或者实习为毕业后面临的升学就业做准备,一边要为毕业设计耗费大量精力。学长给大家整理…

Java---猜数字游戏

本篇文章所实现的是Java经典的猜数字游戏 , 运用简单代码来实现基本功能 目录 一.题目要求 二.游戏准备 三.代码实现 一.题目要求 随机生成一个1-100之间的整数(可以自己设置区间&#xff09;&#xff0c;提示用户猜测&#xff0c;猜大提示"猜大了"&#xff0c;…

SAP系统中的主要采购类型/采购模式总结

在 SAP 系统中,采购类型主要有以下几种: 一、标准采购订单(Standard Purchase Order) 描述:这是最常用的采购类型,用于一次性采购货物或服务。采购部门根据需求部门提出的采购申请,向供应商发出采购订单,明确规定了采购的物料、数量、价格、交货日期等详细信息。 应…

论文笔记(六十三)Understanding Diffusion Models: A Unified Perspective(五)

Understanding Diffusion Models: A Unified Perspective&#xff08;五&#xff09; 文章概括基于得分的生成模型&#xff08;Score-based Generative Models&#xff09; 文章概括 引用&#xff1a; article{luo2022understanding,title{Understanding diffusion models: A…

ThinkPHP 8模型与数据的插入、更新、删除

【图书介绍】《ThinkPHP 8高效构建Web应用》-CSDN博客 《2025新书 ThinkPHP 8高效构建Web应用 编程与应用开发丛书 夏磊 清华大学出版社教材书籍 9787302678236 ThinkPHP 8高效构建Web应用》【摘要 书评 试读】- 京东图书 使用VS Code开发ThinkPHP项目-CSDN博客 编程与应用开…

项目升级Sass版本或升级Element Plus版本遇到的问题

项目升级Sass版本或升级Element Plus版本遇到的问题 如果项目有需求需要用到高版本的Element Plus组件&#xff0c;则需要升级相对应的sass版本&#xff0c;Element 文档中有提示&#xff0c;2.8.5及以后得版本&#xff0c;sass最低支持的版本为1.79.0&#xff0c;所升级sass、…

基于OSAL的嵌入式裸机事件驱动框架——整体架构调度机制

参考B站up主【架构分析】嵌入式祼机事件驱动框架 感谢大佬分享 任务ID &#xff1a; TASK_XXX TASK_XXX 在系统中每个任务的ID是唯一的&#xff0c;范围是 0 to 0xFFFE&#xff0c;0xFFFF保留为SYS_TSK_INIT。 同时任务ID的大小也充当任务调度的优先级&#xff0c;ID越大&#…

Three.js 后期处理(Post-Processing)详解

目录 前言 一、什么是后期处理&#xff1f; 二、Three.js 后期处理的工作流程 2.1 创建 EffectComposer 2.2 添加渲染通道&#xff08;Render Pass&#xff09; 2.3 应用最终渲染 三、后期处理实现示例 3.1 基础代码 四、常见的后期处理效果 4.1 辉光效果&#xf…

HTML特殊符号的使用示例

目录 一、基本特殊符号的使用 1、空格符号&#xff1a; 2、小于号 和 大于号&#xff1a; 3、引号&#xff1a; 二、版权、注册商标符号的使用 1、版权符号&#xff1a;© 2、注册商标符号&#xff1a; 三、数学符号的使用 四、箭头符号的使用 五、货币符号的使用…

JAVA实战开源项目:在线文档管理系统(Vue+SpringBoot) 附源码

本文项目编号 T 038 &#xff0c;文末自助获取源码 \color{red}{T038&#xff0c;文末自助获取源码} T038&#xff0c;文末自助获取源码 目录 一、系统介绍二、演示录屏三、启动教程四、功能截图五、文案资料5.1 选题背景5.2 国内外研究现状5.3 可行性分析 六、核心代码6.1 查…

快速分析LabVIEW主要特征进行判断

在LabVIEW中&#xff0c;快速分析程序特征进行判断是提升开发效率和减少调试时间的重要技巧。本文将介绍如何高效地识别和分析程序的关键特征&#xff0c;从而帮助开发者在编写和优化程序时做出及时的判断&#xff0c;避免不必要的错误。 ​ 数据流和并行性分析 LabVIEW的图形…

UE学习日志#15 C++笔记#1 基础复习

1.C20的import 看看梦开始的地方&#xff1a; import <iostream>;int main() {std::cout << "Hello World!\n"; } 经过不仔细观察发现梦开始的好像不太一样&#xff0c;这个import是C20的模块特性 如果是在VS里编写的话&#xff0c;要用这个功能需要新…

Deep Seek R1本地化部署

目录 说明 一、下载ollama 二、在ollama官网下载模型 三、使用 后记 说明 操作系统&#xff1a;win10 使用工具&#xff1a;ollama 一、下载ollama 从官网下载ollama&#xff1a; ollama默认安装在C盘&#xff0c;具体位置为C:\Users\用户名\AppData\Local\Programs\O…

C# Winform制作一个登录系统

using System; using System.Collections; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms;namespace 登录 {p…

动态规划DP 最长上升子序列模型 总览

最长上升子序列模型 1. 最长上升子序列 1.1 怪盗基德的滑翔伞 1.1.1 登山 1.1.2 合唱队形 1.2 友好城市 1.3 最长上升子序列和 1.4 导弹拦截

怎样在PPT中启用演讲者视图功能?

怎样在PPT中启用演讲者视图功能&#xff1f; 如果你曾经参加过重要的会议或者演讲&#xff0c;你就会知道&#xff0c;演讲者视图&#xff08;Presenter View&#xff09;对PPT展示至关重要。它不仅能帮助演讲者更好地掌控演讲节奏&#xff0c;还能提供额外的提示和支持&#…

论文阅读(七):贝叶斯因果表型网络解释遗传变异和生物学知识

1.论文链接&#xff1a;Bayesian Causal Phenotype Network Incorporating Genetic Variation and Biological Knowledge 摘要&#xff1a; 在分离群体中&#xff0c;数量性状基因座&#xff08;QTL&#xff09;定位可以确定对表型有因果效应的QTL。这些方法的一个共同特点是Q…