数据结构算法-堆(Heap)和优先队列

堆的概念

堆(heap)是计算机科学中一类特殊的数据结构的统称。堆通常是一个可以被看做一棵树的数组对象。堆总是满足下列性质:

  • always greater than its child node/s and the key of the root node is the largest among all other nodes. This property is also called max heap property.
  • always smaller than the child node/s and the key of the root node is the smallest among all other nodes. This property is also called min heap property.

image-20240525103805942

最大堆

最大堆是指在树中,存在一个结点而且该结点有儿子结点,该结点的data域值都不小于其儿子结点的data域值。

image-20240525095717496

最小堆

最小堆是指在树中,存在一个结点而且该结点有儿子结点,该结点的data域值都不大于其儿子结点的data域值。

image-20240525095805275

堆的操作

image-20240525104126741

Heapify

Heapify is the process of creating a heap data structure from a binary tree. It is used to create a Min-Heap or a Max-Heap.

heapify是将heap调整为最大堆或最小堆的过程,我们以最大堆为例,演示调整过程。

找到最后一个非叶子节点

heapify是从当前最后一个非叶子结点开始,一直向下到0.

image-20240525104821576

如何找到最后一个非叶子节点

一个数组(假设长度为n)构成的完全二叉树,index表示节点索引索引,

个人理解: 叶节点的数量大致为其父节点的2倍(子节点最多两个子节点,假设为满完全二叉树),最后一个节点约等于叶节点的第一个节点(约为n/2)-1: 大致为n/2-1

叶节点和(假设四层) 约等于 (1,2,3)层之和

编号层(k)索引(index)层和索引n和索引
1102k-1-1
221,22k-1-1, 2k-1节点2:(6/2)-1 =2
333,4,5,62k-1-1节点6(假设有): 15/2-1=6
447,8,9,10,11,12,13,14

设置当前的为最大元素

int largest = i;
int len = size;  // 数组实际长度
//3. 计算当前节点的左子节点,和右子节点
int left = 2 * i + 1;   //左子节点位置
int right = 2 * i + 2;  //右子节点位置
right = Math.min(right,elements.length-1);

当前节点与左子和右子比较,找到最大值

// 3.1比较左子节点
if (left<size && elements[left] > elements[largest]) {
    largest = left;
}
if (right<size && elements[right] > elements[largest]) {
    largest = right;
}

与当前节点交换最大值

//交换largset
int tmp = elements[largest];
elements[largest] = elements[i];
elements[i] = tmp;
//用户当前节点递归heapify
heapify(largest);

从最后一个非叶子结点开始

从最后一个非叶节点依次递减到0,循环执行以上步骤

for(int i = elements.length/2-1; i>=0;i++){
    heapify(i);
}

heapify完整代码

public void heapify(int curr) {
    //1.找到最后一个非叶节点
    int len = elements.length;
    System.out.println("curr: " + curr);
    //2. 设置当前节点为最大节点
    int largest = curr;

    //3. 计算当前节点的左子节点,和右子节点
    int left = 2 * curr + 1;
    int right = 2 * curr + 2;

    // 3.1比较左子节点
    if (left < size && elements[left] > elements[largest]) {
        largest = left;
    }
    if (right < size && elements[right] > elements[largest]) {
        largest = right;
    }

    //交换largset
    if (largest != curr) {
        int tmp = elements[largest];
        elements[largest] = elements[curr];
        elements[curr] = tmp;
       // 递归地heapify受影响的子树(以新的最大值节点为根)  
       // 这会确保子树也保持最大堆的性质 
        heapify(largest);
    }
}

在堆中添加数据

public void insert(int data) {
    if (size == 0) {
        elements[size++] = data;
    } else {
        elements[size++] = data;
        for (int i = size / 2 - 1; i >= 0; i--) {
            heapify(i);
        }
    }
}

添加第一个数: 1

image-20240527143550935

添加第二个数: 9

第二个数9作为1的左子节点进行比较大于1,交换两个值,largest=1

image-20240527143750166

添加第三个数: 5

5作为第三个数,与它的父节点9比较,小于父节点,所以不做交换。

image-20240527143951187

添加第四个数: 4

第四个节点按照完全二叉树的定义从左向右添加,作为节点(值=1)的子节点。需要heapify(), 节点(值=4)与节点(值=1)进行交换。

image-20240527144122471

删除堆中的元素

选取要删除的元素

image-20240527151059931

int wantedDelIndex;
for(wantedDelIndex =0; wantedDelIndex < size;wantedDelIndex++){
    if(data == elements[wantedDelIndex]) break;
}

将当前元素与最后一个元素交换

image-20240527151153971

/*
  将要删除的元素与最后一个叶节点元素交换
 */
int tmp = elements[wantedDelIndex];
elements[wantedDelIndex] = elements[size-1];
elements[size-1] = tmp;

删除最后一个叶节点

image-20240527152128909

heapify

调用heapify()方法

力扣“前K个高频元素”

https://leetcode.cn/problems/top-k-frequent-elements/description/
给你一个整数数组 nums 和一个整数 k ,请你返回其中出现频率前 k 高的元素。你可以按 任意顺序 返回答案。

示例 1:

输入: nums = [1,1,1,2,2,3], k = 2
输出: [1,2]
示例 2:

输入: nums = [1], k = 1
输出: [1]

使用Map存储每个元素的值和出现频率,再将Map中的Map.entry对象放入,注意: Map.entry对象已经实现了Comparator方法,即可以存入优先队列(优先队列的底层由最小堆完成). 以下给出自己的参考实现。

class Solution {
    public int[] topKFrequent(int[] nums, int k) {
        Map<Integer, Integer> map = new HashMap<>();
        PriorityQueue<Map.Entry<Integer, Integer>> queue = new PriorityQueue<>(Map.Entry.comparingByValue());
        for (int t : nums) {
            map.merge(t, 1, Integer::sum);
        }
        queue.addAll(map.entrySet());
        int n = map.size();
        int[] a = new int[k];
        for (int i = 0; i < n - k; i++) {
            queue.poll();
        }
        for (int i = 0; i < k; i++) {
            a[i] = Objects.requireNonNull(queue.poll()).getKey();
        }
        return a;
    }
}

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

企业选择定制化MES管理系统时需要考虑的核心功能

在当今制造业的数字化转型浪潮中&#xff0c;企业对于实现生产现场透明管理的需求愈发迫切。为了满足这一需求&#xff0c;MES管理系统成为了众多企业的首选解决方案。MES管理系统以其高度的灵活性和可定制性&#xff0c;能够根据不同行业的特性&#xff0c;为企业提供量身定制…

super关键字的使用

就是说我们有个子类和父类。子类继承父类。父类的私有的都不能访问&#xff0c;其他的都能够通过super访问&#xff0c;那么&#xff0c; 那么查找怎么查找呢&#xff0c;分两种情况&#xff0c; 1 子类和父类的属性没重名 直接用属性如n1, 2子类和父类有重名的 用super(…

大事件项目实战

初始化 创建项目 新建api_server文件夹为项目根目录&#xff0c;并在项目中运行如下的命令&#xff0c;初始化管理配置文件&#xff1a; npm init -y 运行如下的命令&#xff0c;安装特定版本的express: npm i express4.17.1 在项目根目录中新建app.js作为整个项目的入口…

深入探索C++模板进阶:掌握非类型参数、特化技巧与分离编译的艺术

目录 非类型模板参数 类模板的特化 概念 函数模板特化 类模板特化 全特化 偏特化 类模板特化应用示例 模板的分离编译 分离编译概念 模板的分离编译 解决方法 模板总结 非类型模板参数 模板参数可分为类型形参和非类型形参。 类型形参&#xff1a; 出现在模板参数列表中&am…

韬光养晦的超绝项目

发展方向 竞技闯关类 可以加入对战系统积累积分&#xff0c;竞技类的接受程度更高&#xff0c;小孩&#xff08;我和我身边大多数人小时候&#xff09;都喜欢玩王者吃鸡这种经济类游戏&#xff0c;开放世界探索&#xff08;本项目、一梦江湖、逆水寒&#xff09;的受众群体年…

8. C++通过epoll+fork的方式实现高性能网络服务器

epollfork 实现高性能网络服务器 一般在服务器上&#xff0c;CPU是多核的&#xff0c;上述epoll实现方式只使用了其中的一个核&#xff0c;造成了资源的大量浪费。因此我们可以将epoll和fork结合来实现更高性能的网络服务器。 创建子进程函数–fork( ) 要了解线程我们先来了解…

Linux下Qt Creator无法输入中文(已解决)

1. 首先确保安装了搜狗输入法&#xff0c;且能正常运行。 2.克隆源码到本地。 git clone https://gitcode.com/fcitx/fcitx-qt5.git 3.检查Qt Creator版本&#xff0c;如下图所示&#xff0c;为基于Qt6的。 4. 进入源码目录&#xff0c;建立build文件夹&#xff0c;修改CMak…

COD20使命召唤20新赛季免费玩 COD20免费体验在哪下

使命召唤20&#xff08;COD20&#xff09;的免费周已经正式启动&#xff0c;这是一个为期一周的特别活动&#xff0c;为玩家们带来了前所未有的游戏体验。在这个特殊的周期里&#xff0c;多人模式和僵尸模式将向公众免费开放&#xff0c;玩家们可以尽情地探索和体验游戏的精彩内…

2022全国大学生数学建模竞赛ABC题(论文+代码)

文章目录 &#xff08;1&#xff09;2022A波浪能最大输出功率&#xff08;2&#xff09;2022B无人机定位&#xff08;3&#xff09;2022C古代玻璃制品成分分析&#xff08;4&#xff09;论文和代码链接 &#xff08;1&#xff09;2022A波浪能最大输出功率 &#xff08;2&#x…

3D开发工具HOOPS在BIM系统中的应用

建筑信息模型是一种革命性的建筑设计、施工和管理方法。它通过创建和利用数字信息来优化建筑项目的设计、施工和运营过程。在这个过程中&#xff0c;3D开发工具HOOPS扮演着至关重要的角色&#xff0c;为BIM系统提供了强大的技术支持和丰富的功能。HOOPS中文网http://techsoft3d…

Linux如何在目录下灵活创建、浏览、删除百万个文件

文章目录 一、创建百万级小文件1、单核CPU情况2、多核CPU情况3、执行效率对比3.1、单核的顺序执行3.2、多核的并发执行 二、如何列出/浏览这些文件1、查看目录下文件的数量2、列出&#xff1f;3、ls -f&#xff08;关闭排序功能&#xff09;3.1、执行效率对比 4、通过重定向导入…

探索Python函数参数的奥秘

新书上架~&#x1f447;全国包邮奥~ python实用小工具开发教程http://pythontoolsteach.com/3 欢迎关注我&#x1f446;&#xff0c;收藏下次不迷路┗|&#xff40;O′|┛ 嗷~~ 目录 一、揭开函数参数的神秘面纱 1. 位置参数&#xff1a;按序传值的基石 2. 关键字参数&#…

作业-day-240527

Cday1思维导图 定义自己的命名空间my_sapce&#xff0c;在my_sapce中定义string类型的变量s1&#xff0c;再定义一个函数完成对字符串的逆置 #include <iostream>using namespace std;namespace my_space {string s1"abc123";string recover(string s){int i0…

C语言基础——数组

{\▁/} ( / 。\ ) / ⊃&#x1f494;\⊃ 为什么我那么努力还是得不到那么多赞 ʕ • ᴥ • ʔ づ♡ど &#x1f389; 欢迎点赞支持&#x1f389; 个人主页&#xff1a;励志不掉头发的内向程序员&#xff1b; 专栏主页&#xff1a;C语言基础&#xff1b; 文章目录 前言…

Spring AOP失效的场景事务失效的场景

场景一&#xff1a;使用this调用被增强的方法 下面是一个类里面的一个增强方法 Service public class MyService implements CommandLineRunner {private MyService myService;public void performTask(int x) {System.out.println("Executing performTask method&quo…

【软件测试】bug篇|软件测试的生命周期|描述bug的要素|bug的级别|bug的生命周期|高频面试题:与开发产⽣争执怎么处理

目录 一、软件测试的⽣命周期 二、BUG 2.1 bug的概念 2.2 描述bug的要素 2.3 bug级别 2.4 bug的⽣命周期 &#x1f4a1;2.5 与开发产⽣争执怎么办&#xff08;⾼频考题&#xff09; &#x1f4a1; 推荐 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&…

java对象的比较

一.PriorityQueue中插入对象 优先级队列在插入元素时有个要求&#xff1a;插入的元素不能是null或者元素之间必须要能够进行比较&#xff0c;那优先级队列中能否插入自定义类型对象呢&#xff1f; 堆中插入元素时&#xff0c;必须要进行元素的比较&#xff0c;而此时Card是没有…

Java入门-java的集合框架

集合概念 集合&#xff0c;有时也称作容器(Container), 是对象的持有者&#xff0c;它们可以有助于高效访问的方式存储的组织对象。以生活中的案例为例&#xff1a; 集合就像装衣服的柜子&#xff0c;衣服就是集合中的元素。 集合框架图 Collection中每次操作的都是一个对象&a…

智慧林业云巡平台 客户端和移动端(支持语音和视频)自动定位巡护,后端离线路线监测

目前现状 无法客观、方便地掌握护林员的到位情况&#xff0c;因而无法有效地保证巡护人员按计划要求&#xff0c;按时按周期对所负责的林区开展巡护&#xff0c;使巡护工作的质量得不到保证。遇到火情、乱砍滥伐等灾情时无法及时上报处理&#xff0c;现场状况、位置等信息描述…

pycharm打开服务器(linux)上的项目

先在本地打开项目 一、项目文件配置 tools-deployment-configuration 新增一个sftp连接 测试服务器是否可以连通 mappings中设置本地路径和服务器上的路径 二、环境配置 先参考文章 复现论文的conda环境&#xff08;win和联网、离线linux&#xff09;_conda复现环境-CSDN博…