数据结构之堆详解

news/2024/11/23 9:30:42/

目录

1.什么是堆

堆的定义

结构体定义与函数接口

堆的初始化

堆的销毁

入堆

向上调整算法

大堆

出堆

向下调整算法

返回堆顶元素

判空

堆的应用


1.什么是堆

知道以上的存储方法,对于完全二叉树,有一个叫做堆的结构,堆本质就是一个完全二叉树,

堆分两种:1.大堆    2.小堆

除了是完全二叉树,大堆需满足任何一个双亲都大于等于孩子,对于小堆,任何一个双亲都小于等于孩子。

堆的定义

我们实现堆就用数组来实现的:这里以实现小堆为例

结构体定义与函数接口

#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
typedef int HPDATAtype;
typedef struct Heap
{HPDATAtype *a;int size;int capacity;
}HP;void Heapinit(HP* f);
void Heapdestroy(HP* f);
void Heappop(HP* f);
void Heappush(HP* f , HPDATAtype x);

堆的初始化

void Heapinit(HP* f)
{//初始有4个空间assert(f);f->a = NULL;f->size = 0;f->capacity = 0;
}

堆的销毁

void Heapdestroy(HP* f)
{assert(f->a);free(f->a);f->a = NULL;
}

入堆

void Heappush(HP* f, HPDATAtype x)
{assert(f);if (f->capacity == f->size){int  newcapacity = f->capacity = 0 ? 4 : f->capacity*2;HPDATAtype* newnode = (HPDATAtype*)malloc(newcapacity);if (newnode == NULL){perror("扩容失败\n");return;}f->a = newnode;f->capacity = f->capacity*2;}f->a[f->size] = x;f->size++;//向上调整算法Adjustup(f->a, f->size - 1);//向下调整算法//Adjustdown(f->a, f->size - 1);
}

在这里在入堆之后,也就是元素赋值到数组之后,根据你对数组的调整,也就是所说的向上调整算法,和向下调整算法,决定是小堆,还是大堆。

向上调整算法

我们这里通过对树所对应的数组元素的关系寻找父亲。 小堆:

void Adjustup(HPDATAtype*a, int child)
{//根据孩子zhaofuqinint parent = (child - 1) / 2;while (child>0){if ( a[child]<a[parent]){HPDATAtype p = a[child];a [child] = a[parent];a[parent]=p;child = parent;parent = (child - 1) / 2;}else {break;}}
}

大堆

这里只需要更改判断条件就变成大堆的调整

void Adjustdown(HPDATAtype* a, int child)
{//根据孩子找父亲int parent = (child - 1) / 2;while (child > 0){if (a[child] > a[parent]){int tmp = a[child];a[child] = a[parent];a[parent] = tmp; child = parent;parent = (child - 1) / 2;}else{break;}}}

出堆

出堆就是最后一个元素换到第一个元素,在size--,之后在进行调整。


void Heappop(HP* f){assert(f);//堆顶元素出堆,最后元素出堆assert(f->size);int tmp = f->a[0];f->a[0] = f->a[f->size - 1];f->a[f->size - 1] = tmp;f->size--;//向下调整Adjustdown(f->a, f->size, 0);
};

向下调整算法

出堆为了不改变原有的父节点与兄弟节点的关系,采用的是将堆底的最后一个与第一个互换,在减减,此时我们仍需要调整堆,采用向下调整算法---即从第一个节点处开始,找作为父节点的儿子节点中较小的那一个,两者比较,循环调整。

因此传参需要堆的大小以及第一个父亲结点坐标也就是0.

void Adjustdown(HPDATAtype* a, int size,int parent)
{int child =parent * 2 +1;while (child<size){if ((child+1<size)&&a[child + 1] < a[child])//若右孩子存在且小于左孩子{++child;}if (a[child] < a[parent]){//交换int tmp = a[child];a[child] = a[parent];a[parent] = tmp;parent = child;child = parent * 2 + 1;}else{break;}}}

返回堆顶元素

HPDATAtype HeapTop(HP* f)
{assert(f);assert(!HeapEmpty(f));return f->a[0];//返回堆顶数据
}

判空

bool HeapEmpty(HP* f)
{if (f->size == 0){return true;}else{return false;}
}

堆的应用

.堆可以用作优先级队列,实现高效的插入和删除操作


.堆可以用来解决海量数据的topk问题,即从大量数据中找出最大或最小的k个数


.堆可以用来进行堆排序,即每次把堆顶元素和堆尾元素交换,然后重新调整堆,直到堆为空


.堆还可以用来实现一些其他的算法,比如哈夫曼编码,Dijkstra算法等

需要注意的是对于向上排序算法还是向下排序算法,他们都是一对一对的使用,从而取决于你是大堆还是小堆,主要体现调整算法中的判断条件。


http://www.ppmy.cn/news/82065.html

相关文章

分布式项目 09.服务器之间的通信和三个工具类

项目的结构&#xff1a;1.通过Nginx首先把访问首页的请求发送到前端web服务器&#xff0c;2.web服务器会根据请求的url中的一些细节&#xff0c;来把相关的请求发送到相关的服务器中&#xff0c;3.相关的服务器会处理业务&#xff0c;并且返回结果到web服务器中&#xff0c;最后…

推荐|x86视觉运动控制一体机VPLC710

正运动技术始终围绕客户需求不断迭代升级产品及开发&#xff0c;积极探索工控自动化高质量发展新路径&#xff0c;着眼于全力为客户提供更优质的产品与服务&#xff0c;特此开发了一款可满足全场景高速高精及中大型产线设备应用需求的x86的IPC形态控制器。 VPLC710产品简介 VP…

CH32V3xx USART 空闲中断+DMA接收

目录 1、CH32V3xx USART简介2、测试程序2.1 USART 初始化配置2.1 发送函数2.1 接收中断1、CH32V3xx USART简介 CH32V3xx系列MCU包含3个同步异步收发器(USART1、2、3)和5个通用异步收发器(UART4、5、6、7、8)。USART模块支持DMA功能,DMA可以实现快速连续收发。使用DMA发送时…

终于!我们把 CEO 炒了,让 ChatGPT 出任 CEO

⚠️ FBI Warning&#xff1a;本文纯属作者自娱自乐&#xff0c;数字人的观点不代表 CEO 本人的观点&#xff0c;请大家不要上当受骗&#xff01;&#xff01; 哪个公司的 CEO 不想拥有一个自己的数字克隆&#xff1f; 想象&#x1f914;一下&#xff0c;如果 CEO 数字克隆上线…

SSM框架学习之spring

Spring 以下是关于Spring Boot学习的一些文档和资源&#xff0c;希望对你有帮助&#xff1a; Spring Boot官方文档&#xff1a;https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/ Spring Boot中文文档&#xff1a;https://www.springcloud.cc/spring-bo…

前沿重器[33] | 试了试简单的prompt

前沿重器 栏目主要给大家分享各种大厂、顶会的论文和分享&#xff0c;从中抽取关键精华的部分和大家分享&#xff0c;和大家一起把握前沿技术。具体介绍&#xff1a;仓颉专项&#xff1a;飞机大炮我都会&#xff0c;利器心法我还有。&#xff08;算起来&#xff0c;专项启动已经…

java多线程1

线程是独立的执行路径程序运行时&#xff0c;即使没有自己创建线程&#xff0c;后台也会有多个线程&#xff0c;如main主线程&#xff0c;gc线程main()是主线程&#xff0c;是系统的入口&#xff0c;用于执行整个程序在一个进程中&#xff0c;若有多个线程&#xff0c;线程的运…

What is the preparatio for running the project wjcat?

I want to know what I should to prepare to do the procedures in the following text "在 wjcatAdmin 里的 seetting.py 配置数据库信息并迁移。具体步骤如下&#xff1a;数据库配置位于 wjcat-release\wjcatAdmin\wjcatAdmin\settings.py 文件中(将 setting.example.p…