堆(数据结构篇)

数据结构之堆(优先队列)

二叉堆

概念

  • 优先队列是一个根据优先性而先去执行操作的一种特殊队列,平常队列是先进先出,但是优先队列是根据优先级选择先出的元素。优先队列的主要操作有插入和删除最小值

  • 堆(heap)通常是指二叉堆,因为二叉堆的使用次数最频繁,所以我们平常认为的堆就是二叉堆

  • 二叉堆:二叉堆是由一颗完全二叉树实现的,完全二叉树是**一颗底层必须从左往右依次插入且底层以上的节点都是填满的树(最后一层也就是叶子节点可以不是填满的,但是已经插入的元素必须是从左到右的中间不空缺元素的)**称为完全二叉树

  • 完全二叉树是一个很有规律的树,因此用一个动态数组实现是效率最好的选择,在动态数组中是按照从上到下从左到右依次插入数组中,数组下标为0处不放元素。

    用数组实现的完全二叉树的性质有:

    1. 对于数组中任意一个位置i上的元素,其左儿子在数组位置2i上右儿子在左儿子后的单元也就是数组下标为(2i+1)的位置,它的父亲在i/2的位置上
    2. 数组下标为0的地方是不放我们要存的元素的

性质

  • 堆也就是通常认为的二叉堆(binary heap),是由一颗完全二叉树实现的
  • 堆中的主要操作有插入和删除最小值操作,堆的删除其实就是删除最小值而不是删除指定值
  • 堆有堆序性质,也就是堆中的任意子树也是一个堆,因此任意节点就应该小于它的子节点,因为堆需要快速查找最小元,因此我们将最小元放在根节点上
  • 结构体应该包含一个数组(动态)堆中存储的有效元素个数数组的容量以便于扩容

最大堆/大根堆:任意节点应该大于它的所有后裔

最小堆/小根堆:任意节点应该小于它的所有后裔

插入操作(上浮)

  • 先遵从堆从上到下,从左到右依次插入,我们将数据按照这个准则插入到数组。
  • 然而,插入后,我们还需要进行检查这个堆是否有堆序性,如果没有就需要进行调整
  • 插入数据跟根节点进行比较,如果根节点的值比插入数据大,就需要交换,然后一路向上检查比较,直到根节点。

删除操作(下沉)

  • 堆的删除操作是删除最小值的操作,而不是删除指定值的操作
  • 我们创建堆时,都将最小值放到根节点,因此删除我们只需要将根节点删除掉
  • 但是删除根节点后,我们的堆序性就无法保证,如何保证堆序性以及堆的性质(也就是完全二叉树的性质)呢
  • 我们需要将根节点的值与叶子层的最右边元素进行交换,然后删除交换后处在叶子节点(也就是原来的根节点)的节点,然后让现在的根节点跟左右子节点的最小节点比较,如果大于就交换,直到检查到叶子节点,则就调整成功了。

构建堆

  • 构建堆的操作就是将一个无序的树,构造成一个堆
  • 一个堆满足完全二叉树的特性以及堆序性,因此我们需要对这个无序树进行调整,让其成为一个堆。

实现代码:

class heap{
public:heap(int maxsize){key=new int[maxsize+1];key[0]=0;for(int i=1;i<maxsize+1;i++){key[i]=0;}size=0;capacity=maxsize;}int find(int data){for(int i=1;i<size;i++){if(key[i]==data){return i;}}cout<<"没有找到"<<endl;return -1;}void adjust(int data){key[size+1]=data;int index=size+1;while(index>0){int i=index;index=index/2;if(key[index]>key[i]){int temp=key[index];key[index]=key[i];key[i]=temp;}}}void insert(int data){if(size==capacity){int *an=new int[2*capacity];capacity=capacity*2;for(int i=0;i<=size;i++){an[i]=key[i];}delete[] key;key=an;}if(key[1]==0){key[1]=data;}else{adjust(data);}size++;}void deladjust(int index){if(index*2<=size){int mn;if(key[index*2+1]==NULL){mn=index*2;}else if(key[index*2]>key[index*2+1]){mn=index*2+1;}else{mn=index*2;}if(key[index]>key[mn]){int temp=key[index];key[index]=key[mn];key[mn]=temp;}deladjust(mn);}return;}void delmin(){key[1]=key[size];key[size]=0;size--;deladjust(1);}void destroy(){for(int i=1;i<=size;i++){key[i]=0;}size=0;cout<<"成功清除堆中数据"<<endl;}void print(){int cnt=1,ans=1;for(int i=1;i<=size;i++){cout<<key[i]<<" ";if(i==ans){cout<<endl;ans=pow(2,cnt)+i;cnt++;}}}
private:int *key;    //动态数组,用来存储树节点的元素int size;    //堆中存在的有效元素个数int capacity;    //数组容量
};

尾言

完整版笔记也就是数据结构与算法专栏完整版可到我的博客进行查看,或者在github库中自取(包含源代码)

  • 博客1: codebooks.xyz
  • 博客2:moonfordream.github.io
  • github项目地址:Data-Structure-and-Algorithms

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

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

相关文章

碳化硅陶瓷膜的生产工艺和应用

一、生产工艺 碳化硅陶瓷膜的生产工艺多样&#xff0c;其中浸渍提拉法和喷涂法为两大主流技术。 浸渍提拉法 浸渍提拉法是一种广泛应用的制备方法。其过程主要包括&#xff1a;先将陶瓷颗粒或者聚合物前体分散在水或有机溶剂中&#xff0c;形成均质稳定的制膜液。随后&#xff…

Jenkins macos 下 failed to create dmg 操作不被允许hdiutil: create failed - 操作不被允许?

解决方案&#xff1a; 打开设置&#xff0c;选择“隐私与安全”&#xff0c;选择“完全磁盘访问权限”&#xff0c;点击“”&#xff0c;选择jenkins的路径并添加。 同理&#xff0c;添加java的访问权限。

Python14 面向对象编程

1.什么是面向对象编程OOP Python的面向对象编程&#xff08;Object-Oriented Programming&#xff0c;简称OOP&#xff09;是一种编程范式&#xff0c;它使用“对象”来设计应用程序和计算机程序。这些对象由数据和能够操作这些数据的方法组成。面向对象编程的主要目标是提高软…

Scala入门介绍

Scala 是一种强大的多范式编程语言&#xff0c;旨在融合面向对象编程和函数式编程的特性。它运行在 Java 虚拟机&#xff08;JVM&#xff09;上&#xff0c;因此可以无缝地与 Java 库进行交互。以下是对 Scala 的入门介绍&#xff0c;并附带了一些基本代码示例。 环境设置 首先…

Webpack4从入门到精通以及和webpack5对比_webpack现在用的是哪个版本

3.1 打包样式资源css-loader、style-loader… {// 匹配哪些文件test: /\.less$/,// 使用哪些loader进行处理use: [// use数组中loader执行顺序&#xff1a;从右到左&#xff0c;从下到上&#xff0c;依次执行(先执行css-loader)// style-loader&#xff1a;创建style标签&#…

HTML内容回顾

<!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>Title</title> </head> <body><!--HTML标签&#xff1a;“标题标签 h1-h6段落标签 p换行 br水平分割线 hr空格 加粗 <…

Total CAD Converter与Total Excel Converter软件分享

1.软件介绍 Total CAD Converter Total CAD Converter 是一款功能强大的工具&#xff0c;能够将 CAD 文件转换为多种格式&#xff0c;如 PDF、TIFF、JPEG、BMP、WMF、PNG、DXF、BMP、CGM、HPGL、SVG、PS 和 SWF 等。其支持的源格式丰富多样&#xff0c;包括 dxf、dwg、dwf、d…

leetcode 面试题 08.12. 八皇后

. - 力扣&#xff08;LeetCode&#xff09; 设计一种算法&#xff0c;打印 N 皇后在 N N 棋盘上的各种摆法&#xff0c;其中每个皇后都不同行、不同列&#xff0c;也不在对角线上。这里的“对角线”指的是所有的对角线&#xff0c;不只是平分整个棋盘的那两条对角线。 注意&a…

达梦数据统计库表中的数据量

1、创建存储表数据的表结果 create table sysdba.table_count (owner varchar(100),table_name varchar(100),cnt int); 2、创建统计表的存储过程&#xff08;上千万表&#xff0c;可能存在性能慢的问题&#xff09; create or replace procedure sysdba.cut_table_number A…

【C++】一个极简但完整的C++程序

一、一个极简但完整的C程序 我们编写程序是为了解决问题和任务的。 1、任务&#xff1a; 某个书店将每本售出的图书的书名和出版社&#xff0c;输入到一个文件中&#xff0c;这些信息以书售出的时间顺序输入&#xff0c;每两周店主会手工计算每本书的销售量、以及每个出版社的…

Java 的多线程和并发处理,在项目中是如何使用它?

在Java开发中&#xff0c;多线程和并发是我们经常需要处理的问题。它们能够让我们的应用在完成一些耗时任务的同时&#xff0c;仍然保持对用户的响应&#xff0c;提高了应用的性能和用户体验。接下来&#xff0c;让我们来详细地了解一下Java中的多线程和并发处理。 Java中的多线…

Vue74-路由传参2

一、$route中的params参数 二、在配置路由的index.js文件中&#xff0c;声明传参 占位符用的什么名字&#xff0c;params里面的key就是什么。 三、<router-link>标签中传参 3-1、to字符串写法 3-2、to的对象写法 注意&#xff1a;若是用params携带参数&#xff0c;不…

返利系统中的支付集成与交易处理

返利系统中的支付集成与交易处理 大家好&#xff0c;我是免费搭建查券返利机器人省钱赚佣金就用微赚淘客系统3.0的小编&#xff0c;也是冬天不穿秋裤&#xff0c;天冷也要风度的程序猿&#xff01; 在现代电子商务平台中&#xff0c;返利系统不仅仅是吸引用户的利器&#xff…

typescript中declear是干什么的?

问: typescript中declear是干什么的? 回答: 在 TypeScript 中&#xff0c;declare 关键字的主要作用是用来定义类型声明而不是真正的实现或变量。这种机制允许开发者在 TypeScript 中描述与外部 JavaScript 环境交互的接口&#xff0c;或者引入其他模块的类型定义&#xff0…

mysql的安装以及分享navicat for MySQL

前言 根据网上分享的安装方法以及自己遇到的问题解决方法 一、mysql是什么&#xff1f; mysql 是一个开放源码的小型关联式数据库管理系统 二、安装过程 1.下载安装包 下载地址&#xff1a;MySQL :: Download MySQL Community Server 跳过直接下载&#xff0c;解压即可 …

DPDK的Cache预取和Cache一致性

1.什么是Cache预取 众所周知&#xff0c;CPU访问Cache中的数据是比访问内存中的数据是要快的&#xff0c;而因为程序都有时间局部性和空间局部性&#xff0c;时间局部性简单来说就是某一条或几条指令在一段时间内会被CPU多次执行&#xff1b;空间局部性简单来说就是某一段数据块…

五十五、openlayers官网示例Loading Spinner解析——给地图添加loading效果,瓦片图层加载时等待效果

官网demo地址&#xff1a; Loading Spinner 这篇介绍了一个非常简单的loading效果 利用地图的loadstart和loadend事件&#xff0c;动态的添加和删除class名。 map.on("loadstart", function () {map.getTargetElement().classList.add("spinner");});map…

Vue72-路由传参1

一、需求 点击哪个消息&#xff0c;就展示哪个消息的详情 这是一个三级路由&#xff01; 给路由组件&#xff1a;detail.vue传递消息数据。 二、代码步骤 2-1、编写路由组件 从$route.query属性里面获取传参 2-2、编写路由规则 2-3、编写路由标签&#xff0c;传参 1、to的字…

Ncorr使用过程的问题解答

问题系列 文章目录 问题系列前言一、如何更改单位&#xff1f;情景&#xff1a;DIC Analysis 二、拉格兰日和欧拉绘图的区别直观 三、控制图像中的显示条上下界限问题展示&#xff1a;解决方案&#xff1a; 更新动态 前言 主要用于记录使用过程中出现的相关问题。 一、如何更改…

数据结构:为什么说链表是顺序表的升级版(c语言实现)

前言&#xff1a; 我们在之前的几篇文章中详细的讲解了顺序表的特点&#xff0c;增删改查操作和动态顺序表的优点&#xff0c;并使用顺序表的底层结构实现了通讯录项目&#xff0c;似乎顺序表是一个非常完美的数据结构&#xff0c;它可以实现按照需求实现增删查改&#xff0c;对…