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

堆【数据结构C语言版】【 详解】

目录-笔记整理

  • 一、思考
  • 二、堆概念与性质
  • 三、堆的构建、删除、添加
    • 1. 构建
    • 2. 删除
    • 3. 添加
  • 四、复杂度分析
    • 4.1 时间复杂度
    • 4.2 空间复杂度
  • 五、总结

一、思考

设计一种数据结构,来存放整数,要求三个接口:
1)获取序列中的最值(最大或最小)
2)添加元素
3)删除最值(最大或最小)

分析:

1)如果使用无序的线性表来实现,则需要发现获取最值、删除最值都需要遍历全部数据,复杂度为O(n)
2)如果使用有序的线性表,则查找并删除最值是虽是O(1)级别,但插入一个元素要重新进行排序,最好情况也是O(n)
3)如果平衡二叉查找树实现,虽然查找、插入、删除复杂度是O(log<sub>2</sub>n)级别,但其实现程度复杂,功能多,对于仅实现三个接口来说是”大炮打蚊子“,得不尝失。而使用”堆“能很好实现三种接口,且时间复杂度较低,获取最大值O(1),添加、删除都为O(log<sub>2</sub>n)

(注:这里的堆不是内存模型里的”堆空间“,勿要混淆)

二、堆概念与性质

堆(Heap)是一种数据结构,物理存储采用顺序表,其元素必须满足的性质是:
{ k i ≤ k 2 i + 1 k i ≤ k 2 i 或 { k i ≥ k 2 i + 1 k i ≥ k 2 i \lbrace^{k_i \leq k_{2i}}_{k_i \leq k_{2i+1}} 或 \lbrace^{k_i \geq k_{2i}}_{k_i \geq k_{2i+1}} {kik2i+1kik2i{kik2i+1kik2i
我们称前者为小顶堆(或小根堆),后者为大顶堆(或大根堆)。观察发现,这和完全二叉树的性质5很一样,因此可以逻辑上理解堆为一棵完全二叉树。
例如:序列(5,7,6,9,8,10)满足小根堆的性质在这里插入图片描述
这棵完全二叉树的根元素又叫堆顶元素,也是序列中的最小值,因此,每次查找最小值只需要获取堆顶元素即可,添加一个元素后,需要对堆重新进行调整每个元素满足堆性质,成为一个新堆;删除元素就是堆顶元素出堆,然后重新调整元素位置,直到全部元素满足堆性质,成为一个新堆。

三、堆的构建、删除、添加

1. 构建

(以小顶堆为例)
如何使一个序列变成满足堆性质的序列,并且具有添加、删除、获取最值三大接口?需要思考两个问题
1)如何由该混乱的序列构建一个堆?
2)往堆里添加、删除(删除堆顶)元素后,如何调整剩余元素成为一个新的堆?

已知一个混乱序列(10,8,6,9,7,5),和一个空堆H,然后遍历序列,每遍历一个序列往空堆添加元素,既要考虑每个元素满足堆的性质,又要思考新添加的元素位置(放在 i i i的位置还是 i + 1 i+1 i+1的位置),发现这种代码逻辑很难实现。由堆的性质和完全二叉树的性质类似,把已知的混乱序列逻辑上形象的看成一个完全二叉树。那么问题就转化为如何把一个”混乱“的完全二叉树转变为一棵小根堆对于的完全二叉树
在这里插入图片描述

观察图发现,我们只需要从非叶子 ⌊ n / 2 ⌋ \lfloor n/2\rfloor n/2结点开始,以它为根,对其根以及根的所有后代元素进行调整使其成为一棵小根堆,直到 ⌊ n / 2 ⌋ − 1 \lfloor n/2\rfloor-1 n/21 ~ 1 1 1位置为根元素都调整完毕,构建堆完成。
如何调整?
在这里插入图片描述
(注:假设现在有一个小根堆序列,其对应的完全二叉树如上图所示)
1)堆顶元素输出或出堆,让表尾元素(11)覆盖(5)并删除表尾元素
2)根(11)和其左右孩子(7,6)中最小的比较,发现6比11小,则6和11交换位置,这时以11为根的子树继续调整,10比11小,则互换位置…直到叶子结点(若中途发现根比孩子中最小的还小,则操作结束,该棵子树已经调整好了)
知道了如何调整,那么堆的构建就是从非叶子 ⌊ n / 2 ⌋ \lfloor n/2\rfloor n/2结点为根的树进行调整,直到 ⌊ n / 2 ⌋ − 1 \lfloor n/2\rfloor-1 n/21 ~ 1 1 1位置为根的每棵树都调整一遍,即堆构建完成

typedef int HeapType;
//构建堆,传入一个无序序列和序列长度,时间复杂度为O(n)
HeadType* CreateHeap(HeapType *H,int length){//由无序序列 H构建堆,该序列从索引0开始 int s;for(s=length/2-1;s>=0;s--){//建立堆AdjustHeap(H,s,length);//调整函数}return H;
}//堆排序 ---O(nlogn)
void HeapSort(HeapType *H){int s;int top;//堆顶元素出堆,表尾元素覆盖堆顶(删除表尾元素,即空出表尾单元),原堆顶元素放在表尾for(s=length;s>1;s--){//进行length-1次出堆,直到堆中只剩一个元素(该元素的索引:0)top=H[0];H[0]=H[s-1];AdjustHeap(H,0,s-1);H[s-1]=top;} 
}

2. 删除

堆中的删除操作,就是删除堆顶元素,其步骤和上文的如何调整一致,其调整函数如下

void AdjustHeap(HeapType*H,int s,int len){	//s=len/2-1//保存以索引s位置元素为根,此时s位置的结点并不满足最小堆的性质,其//他所有结点(s到len-1)位置的结点满足小顶堆的性质 int rc=H[s];int i;for(i=2*s+1;i<len;i=2*i+1){//由完全二叉树的性质:孩子结点和双亲结点的索引关系(注:结点位置从索引0开始,因此i=2*s+1而不是i=2*s)if(i<len-1&&H[i]>H[i+1])i++;//索引i是s孩子中的最小元素的索引if(rc<=H[i]) break;//若索引s处的元素小于孩子中最小的一个,则调整结束H[s]=H[i];s=i;}H[s]=rc;
}

3. 添加

往堆中添加元素,就是先把新元素放在堆的末端,再对新元素结点执行向上的操作,即让其和双亲结点比较,若新元素结点小于双亲结点则它们互换位置,若互换后,再于其双亲比较、交换,直到整棵树的根结点(索引为0的元素),若中途遇到双亲小于新元素的,则执行向上的操作结束,添加完毕

void addElement(HeapType *H,HeapType e,int len){//注:这里假设数组长度大(不会越界),len是元素的个数int newIndex=len;//新元素的索引int i=(newIndex+1)/2-1;//i是新元素的双亲的索引int eElem=e;//暂存新元素for(i;i>=0;i=(i-1)/2{//向上执行到根(0号结点)if(tElem<H[i]){H[newIndex]=H[i];newIndex=i;}else{break;	}}H[newIndex]=eElem;
}

四、复杂度分析

4.1 时间复杂度

创建堆,是从非叶子结点 ⌊ n / 2 ⌋ \lfloor n/2\rfloor n/2位置的元素开始到根,要调整的内部结点总数有 ⌊ n / 2 ⌋ \lfloor n/2\rfloor n/2,这些结点分布在多个层次,而构建堆过程中,每次循环都要调用一次调整函数AdjustHeap(),其每次执行调整函,其中需要比较的次数和其结点所在的树中的层次到叶子结点的深度有关(最坏的情况下)。
推导过程如下:
假设已知现在有目标堆是一个满堆,即其对应结点总数为n=2h-1的完全二叉树(也是满二叉树),深度为h,根结点处于第1层。我们处于第h-1层的每个非叶子结点向下调整时最多比较一次,第h-2层的最多比较2次…,第一层的根结点则比较n-1次(注:这里没计入筛选孩子中最小值的那一次比较)。第一层结点数:21-1=1,第二层结点数:22-1…第h-1层的结点总数:2h-2,则总的比较次数S=可能比较抽象,如下表

树的层次结点数比较次数
第1层1h-1
第2层2h-2
第3层22h-3
h-12h-21

则总的比较次数:
S = ( h − 1 ) + 2 ∗ ( h − 2 ) + 2 2 ∗ ( h − 3 ) + . . . + 2 h − 3 ∗ 2 + 2 h − 2 ∗ 1 = 2 h − h − 1 S=(h-1)+2*(h-2)+2^2*(h-3)+...+2^{h-3}*2+2^{h-2}*1=2^h-h-1 S=(h1)+2(h2)+22(h3)+...+2h32+2h21=2hh1

又由于n = 2h - 1,即 h=log2(n+1),则代入上式中,S=n-h,即创建堆时总比较次数S为O(n)级。往往堆排序过程中,就包含建堆(O(n))和排序两个过程,后者每输出一个堆顶元素,则执行一次对根结点的调整(比较的次数规模:O(h)),即时间复杂度为:O(log2n),综合为:O(nlog2n)

4.2 空间复杂度

常数级:O(1)

五、总结

堆排序,在排序过程中使用常数个辅助单元,其建堆时间为O(n),之后执行n-1次对当前的根向下的操作,不管给定的初始序列是有序还是无序,其用堆来排序的最好、最坏、平均时间复杂度均为:O(nlog2n),同时它是一种不稳定的排序,虽然堆排序速度很快,和快速排序时间复杂度一个水平,但其速度却不如快速排序(和时间复杂度的常数因子有关)。快速排序虽然很快,但是最坏的情况下时间复杂度达到O(n2),空间复杂度达到O(n)
(注:一般说某排序算法时间复杂度是多少,通常指平均情况下的)

相关文章:

堆【数据结构C语言版】【 详解】

目录-笔记整理 一、思考二、堆概念与性质三、堆的构建、删除、添加1. 构建2. 删除3. 添加 四、复杂度分析4.1 时间复杂度4.2 空间复杂度 五、总结 一、思考 设计一种数据结构&#xff0c;来存放整数&#xff0c;要求三个接口&#xff1a; 1&#xff09;获取序列中的最值&#…...

初识React

在最新写需求的时候&#xff0c;我遇到了一个需求&#xff0c;这个需求改后端改的不算多&#xff0c;而且也比较简单&#xff0c;但是在改前端的时候&#xff0c;很复杂。因为我们这个项目用的是React做前端的&#xff0c;而我对于前端知识没有了解&#xff0c;所以理解很多代码…...

VUE 开发——AJAX学习(三)

一、async函数和await async和await关键字让我们可以用一种更简洁的方式写出基于Promise的异步行为&#xff0c;而无需刻意地链式调用Promise async写在函数声明的前面&#xff1b;在async函数内&#xff0c;使用await关键字&#xff0c;获取Promise对象“成功状态”结果值 &…...

C++杂项

作业&#xff1a; 将之前实现的顺序表、栈、队列都更改成模板类 顺序表 #include <iostream>using namespace std;template<typename T>class SeqList { private:T *ptr;int size; //总长度int len 0; //当前顺序表实际长度public://初始…...

Gelatinous Cube Sphere - Bonus Files 2 - Atavism

这是Gelatinous Cube & Sphere Pack的奖励文件包。 奖励文件&#xff1a; ⭐ 概念艺术 也可在Monster Bundle #2中使用。 下载&#xff1a;​​Unity资源商店链接资源下载链接...

锐捷—NAT地址映射+IPsec隧道

任务目标 在出口路由器R3上将R5私网地址1对1映射的公网地址与R1建立IPsec隧道&#xff0c;使得R4在访问R5的映射公网地址时&#xff0c;可以进行IPsec隧道的转发 要求&#xff1a; 1、R4和R5可通过NAT转换正常访问互联网地址&#xff08;R2的lo0&#xff09; 2、R5的私网地…...

index.html 调用 ajax

index.html <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><title>AJAX 请求示例</title><script>// 封装 Ajax 为公共函数&#xff1a;传入回调函数 success 和 failfunction myAjax (url, suc…...

uniapp学习(003-1 vue3学习 Part.1)

零基础入门uniapp Vue3组合式API版本到咸虾米壁纸项目实战&#xff0c;开发打包微信小程序、抖音小程序、H5、安卓APP客户端等 总时长 23:40:00 共116P 此文章包含第11p-第p14的内容 文章目录 vue3使用介绍插值表达式例子时间戳随机数输出函数的值 ref响应式数据变量v-bind 绑…...

计算机毕业设计 基于深度学习的短视频内容理解与推荐系统的设计与实现 Python+Django+Vue 前后端分离 附源码 讲解 文档

&#x1f34a;作者&#xff1a;计算机编程-吉哥 &#x1f34a;简介&#xff1a;专业从事JavaWeb程序开发&#xff0c;微信小程序开发&#xff0c;定制化项目、 源码、代码讲解、文档撰写、ppt制作。做自己喜欢的事&#xff0c;生活就是快乐的。 &#x1f34a;心愿&#xff1a;点…...

JavaScript网页设计案例深度解析:从理论到实践

前言 在现代前端开发中&#xff0c;JavaScript 是赋予网页生命的关键技术。静态的 HTML 和 CSS 虽然能创建美观的页面&#xff0c;但当我们需要增强用户交互和页面响应时&#xff0c;JavaScript 无疑成为最得力的工具。从程序员的角度来看&#xff0c;JavaScript 设计不仅仅是…...

spark-sql建表数据同步到hive

1、基础环境 组件版本备注hadoop3.4.0官方下载hive3.1.3自编译sparkspark-3.5.3-bin-hadoop3官方下载&#xff0c;需要内置hive的jar相关内容paimon0.9.0Maven官方下载jdk1.8.0_41maven3.9.6固定版本 2、停止服务、清理日志 先停止&#xff0c;清理数据 sudo kill -9 $(ps -ef…...

Django上下文处理器

1创建 &#xff08;如frontend目录下&#xff09;category_processors文件&#xff1a; def categories(request):from backend.models import Categorycategory_list Category.objects.all()return {category_list:category_list}这里&#xff0c;必须返回一个字典。 2&…...

旭升集团携手纷享销客,构建全方位客户关系管理平台

宁波旭升集团股份有限公司&#xff08;以下简称“旭升集团”&#xff09;自2003年成立&#xff0c;总部位于中国宁波&#xff0c;集团设有压铸、锻造、挤压、集成四大事业部&#xff0c;在亚洲、欧洲、美洲等地均设立研发中心及制造基地&#xff0c;产品主要覆盖新能源汽车的电…...

uniapp 知识点

自定义导航 在page.json navigationstyle":"custom"navigateTo传参 页面传参只能onLoad(option)里面拿 px和upx的关系 在750设计图中&#xff0c;1px1upx 路由 navigateBack返回上一页 重定向 其实就是把当前页面干掉了 公共组件和页面共同点 computed,watc…...

慢病中医药膳养生食疗管理微信小程序、基于微信小程序的慢病中医药膳养生食疗管理系统设计与实现、中医药膳养生食疗管理微信小程序的开发与应用(源码+文档+定制)

博主介绍&#xff1a; ✌我是阿龙&#xff0c;一名专注于Java技术领域的程序员&#xff0c;全网拥有10W粉丝。作为CSDN特邀作者、博客专家、新星计划导师&#xff0c;我在计算机毕业设计开发方面积累了丰富的经验。同时&#xff0c;我也是掘金、华为云、阿里云、InfoQ等平台…...

解决 Android WebView 无法加载 H5 页面常见问题的实用指南

目录 1. WebView 简介 2. 常见问题 3. 网络权限设置 4. 启用 JavaScript 5. DOM Storage 的重要性 6. 处理 HTTPS 问题 7. 设置 WebViewClient 8. 调试工具 9. 其他调试技巧 10. 结论 相关推荐 1. WebView 简介 Android WebView 是一种视图组件&#xff0c;使得 And…...

Ollama本地部署大模型及应用

文章目录 前言一、下载安装1.Mac2.Windows3.linux4.docker5.修改配置&#xff08;可选&#xff09;1.linux系统2.window 系统3.mac系统 二、Ollama使用1.命令2.模型下载3.自定义模型4.API 服务 三、Open WebUI 使用四、Dify使用 前言 Ollama 是一个专注于本地部署大型语言模型…...

读代码UNET

这个后面这个大小怎么算的&#xff0c;这参数怎么填&#xff0c;怎么来的&#xff1f; 这是怎么看怎么算的&#xff1f; 这些参数设置怎么设置&#xff1f;卷积多大&#xff0c;有什么讲究&#xff1f;...

【java】前端RSA加密后端解密

目录 1. 说明2. 前端示例3. 后端示例3.1 pom依赖3.2 后端结构图3.3 DecryptHttpInputMessage3.4 ApiCryptoProperties3.5 TestController3.6 ApiCryptoUtil3.7 ApiDecryptParamResolver3.8 ApiDecryptRequestBodyAdvice3.9 ApiDecryptRsa3.10 ApiCryptoProperties3.11 KeyPair3…...

机器学习 | Scikit Learn中的普通最小二乘法和岭回归

在统计建模中&#xff0c;普通最小二乘法&#xff08;OLS&#xff09;和岭回归是两种广泛使用的线性回归分析技术。OLS是一种传统的方法&#xff0c;它通过最小化预测值和实际值之间的平方误差之和来找到数据的最佳拟合线。然而&#xff0c;OLS可以遭受高方差和过拟合时&#x…...

代码随想录冲冲冲 Day60 图论Part11

97. 小明逛公园 floyd算法 其实就是先用i和j拼成一个平面 然后看每次从i到j距离 这里分两种情况 1.中间没有经过别的点 2.中间有经过别的点 那么最小步数就要取这两个的最小值 所有根本逻辑是i j确定一个面 再通过不同的k去看每一个中间点 所以k要在最外层 上一次的值要…...

golang web笔记-1.创建Web Server和Handler请求

1. 创建http web server的两个方法 1.1. 方式一&#xff1a;http.ListenAndServe(addr string, handler Handler) addr string&#xff1a;监听地址&#xff0c;如果为"" ,那么就是所有网络接口的80接口handler Handler&#xff1a;如果为nil&#xff0c;那么就是D…...

【Python】Copier:高效的项目模板化工具

Copier 是一个开源的 Python 工具&#xff0c;用于基于项目模板快速生成新项目。它通过灵活的模板化系统&#xff0c;使开发者可以快速创建、维护和更新项目模板&#xff0c;从而自动化项目的初始化流程。无论是简单的文件复制&#xff0c;还是复杂的项目结构配置&#xff0c;C…...

Spring系列 BeanPostProcessor

文章目录 BeanPostProcessor注册时机执行时机 InstantiationAwareBeanPostProcessorSmartInstantiationAwareBeanPostProcessor 本文源码基于spring-beans-5.3.31 参考&#xff1a;https://docs.spring.io/spring-framework/reference/core/beans/factory-extension.html#beans…...

Qualitor processVariavel.php 未授权命令注入漏洞复现(CVE-2023-47253)

0x01 漏洞概述 Qualitor 8.20及之前版本存在命令注入漏洞,远程攻击者可利用该漏洞通过PHP代码执行任意代码。 0x02 复现环境 FOFA&#xff1a;app"Qualitor-Web" 0x03 漏洞复现 PoC GET /html/ad/adpesquisasql/request/processVariavel.php?gridValoresPopHi…...

SpringBoot的概述与搭建

目录 一.SpringBoot的概述 二.SpringBoot 特点 三.SpringBoot 的核心功能 3.1起步依赖 3.2自动配置 四.SpringBoot 开发环境构建 五.SpringBoot 配置文件 六.SpringBoot数据访问管理 七.springboot注解 八.springboot集成mybatis 九.springboot全局异常捕获与处理 一…...

视频集成与融合项目中需要视频编码,但是分辨率不兼容怎么办?

在众多视频整合项目中&#xff0c;一个显著的趋势是融合多元化的视频资源&#xff0c;以实现统一监管与灵活调度。这一需求促使项目团队不断探索新的集成方案&#xff0c;确保不同来源的视频流能够无缝对接&#xff0c;共同服务于统一的调看与管理平台&#xff0c;进而提升整体…...

kafka 换盘重平衡副本 操作流程

一、起因 kakfa某块数据盘损坏&#xff0c;且数据无法恢复&#xff0c;需清空换新盘 二、梳理操作流程 查看topic信息 sh ./kafka-topics --bootstrap-server ***:9092 --list --exclude-internal 查看某个topic数据分布情况 sh ./kafka-topics --bootstrap-server ***:…...

vue3.0 + element plus 全局自定义指令:select滚动分页

需求&#xff1a;项目里面下拉框数据较多 &#xff0c;一次性请求数据&#xff0c;体验差&#xff0c;效果就是滚动进行分页。 看到这个需求的时候&#xff0c;我第一反应就是封装成自定义指令&#xff0c;这样回头用的时候&#xff0c;直接调用就可以了。 第一步 第二步&…...

HarmonyOS/OpenHarmony 离线加载web资源,并实现web资源更新

关键词&#xff1a;h5离线包加载、h5离线包更新、沙箱 在上一篇文章中&#xff0c;我们已经介绍了如何将 rawfile 资源文件中的文件数据拷贝到沙箱下&#xff0c;那么该篇文章将介绍如何加载该沙箱目录下的文件资源&#xff08;此处以打包后的web资源为例&#xff09;&#xf…...

黄骅市领导班子最新调整/百度seo招聘

Java Enum原理 public enum Size{ SMALL, MEDIUM, LARGE, EXTRA_LARGE }; 实际上&#xff0c;这个声明定义的类型是一个类&#xff0c;它刚好有四个实例&#xff0c;在此尽量不要构造新对象。 因此&#xff0c;在比较两个枚举类型的值时&#xff0c;永远不需要调用equals方法&…...

个人网站icp备案网/百度一下点击搜索

题目背景 学生在我们USACO的竞赛中的得分越多我们越高兴。 我们试着设计我们的竞赛以便人们能尽可能的多得分,这需要你的帮助 题目描述 我们可以从几个种类中选取竞赛的题目,这里的一个"种类"是指一个竞赛题目的集合,解决集合中的题目需要相同多的时间并且能得到相同…...

it培训骗局/最好的关键词排名优化软件

微信小程序picker异步获取选择项 文章目录微信小程序picker异步获取选择项前言一、微信小程序picker配置二、使用示例wxmljs三、问题点总结***当 range 是一个 Object Array 时&#xff0c;通过 range-key 来指定 Object 中 key 的值作为选择器显示内容关键配置range-key总结前…...

网站做显卡评测软件/google推广平台怎么做

Seems like a lot of my posts lately have started with something like "Heres a weird IE bug" or "Heres something odd in .NET" but... 似乎我最近的许多帖子都是以“这是一个奇怪的IE错误”或“这是.NET中的奇怪内容”开头的&#xff0c;但是... He…...

浅谈政府门户网站建设/上海站优云网络科技有限公司

概述 通过可视化设置好ip地址&#xff0c;子网掩码&#xff0c;网关&#xff0c;dns后&#xff0c;重启电脑或者关机后&#xff0c;网卡的网关会自动消失&#xff0c;自己不见了&#xff0c;导致上不去网。 解决办法 方法一&#xff1a;通过注册表解决 1、开始–运行–输入“…...

山东平台网站建设价位/百度电脑版入口

SpringMVC——处理json、文件上传和下载、拦截器、国际化一、springmvc处理json1.1 HttpMessageConverter介绍1.2 SringMVC响应json数据示例&#xff08;重点&#xff09;1.2.1 返回json格式的自定义类型对象1.2.2 返回json格式的List集合1.2.3 返回String是文本数据1.3 发送js…...