【手写大跟堆详解】

news2024/11/17 8:50:40

文章目录

  • 大跟堆介绍
  • 大跟堆的结构
  • 大跟堆的应用场景
  • 大跟堆的代码实现

大跟堆介绍

大根堆(Max Heap)是一种特殊的二叉树结构,它满足以下两个条件:
1.完全二叉树:大根堆是一棵完全二叉树,即除了最后一层外,其余每一层的节点都是满的,最后一层的节点都集中在最左边。
2.堆性质:每个节点的值都大于或等于其子节点的值。
大根堆的典型操作包括插入,获取root节点的最大值。
在这里插入图片描述

大跟堆的结构

大根堆的结构
大根堆可以用数组来表示,因为它是一棵完全二叉树。对于一个存储在数组中的大根堆:
根节点的索引为 0。
给定一个节点的索引位置i:
父节点的索引为 (i - 1) / 2。
左子节点的索引为 2 * i + 1。
右子节点的索引为 2 * i + 2。

大跟堆的应用场景

大根堆(Max Heap)在许多算法和应用中都有重要的作用,特别是在需要频繁访问最大元素的场景中。以下是一些常见的应用场景:

  1. 优先队列
    优先队列是一种特殊的队列,每次出队的元素都是队列中优先级最高的元素。大根堆可以用来实现优先队列,其中堆顶元素始终是优先级最高的元素。
    应用举例:
    操作系统的任务调度:调度器选择优先级最高的任务进行执行。
    网络数据包处理:路由器处理优先级最高的数据包。
  2. 堆排序
    堆排序是一种利用堆数据结构设计的排序算法。其基本思想是将待排序序列构建成一个大根堆,此时整个序列的最大值即为堆顶元素。将堆顶元素移出堆(与堆的最后一个元素交换),然后对剩余元素重新构建堆,反复执行上述操作,直到所有元素有序。
    应用举例:
    大数据集的排序:在需要对大量数据进行排序时,堆排序的空间效率较高。
  3. 动态数据流中的最大值
    在处理动态数据流时,使用大根堆可以实时维护当前数据流中的最大值。
    应用举例:
    股票交易系统:实时维护当前交易中的最大交易量。
    传感器数据监控:实时监控传感器数据流中的最大值。
  4. 找到第 K 大的元素
    在一个无序数组中查找第 K 大的元素,可以使用大根堆来实现。首先构建一个包含数组中前 K 个元素的大根堆,然后遍历数组剩余元素,如果当前元素小于堆顶元素,则替换堆顶元素并调整堆,最终堆顶元素即为第 K 大的元素。
    应用举例:
    排名系统:在一组分数中找到第 K 高的分数。
    数据分析:在一组数据中找到第 K 大的数据点。
  5. 合并多个有序序列
    在合并多个有序序列时,可以使用大根堆来保持当前最小元素的顺序。将每个序列的首元素插入大根堆,然后每次取出堆顶元素并插入其所在序列的下一个元素,直到所有元素都被处理完毕。
    应用举例:
    外部排序:当数据量大到无法全部放入内存时,可以先将数据分块排序,然后合并多个有序块。
    多路归并排序:将多个有序的输入流合并为一个有序的输出流。
  6. 图的最短路径算法(如 Dijkstra 算法)
    在 Dijkstra 算法中,需要使用优先队列来选择当前未访问节点中距离起点最近的节点。大根堆可以用来实现这个优先队列,以保证每次都能高效地选择最短路径的下一步节点。
    应用举例:
    地图导航系统:计算从一个地点到另一个地点的最短路径。
    网络路由优化:寻找数据包在网络中传输的最优路径。
  7. 事件驱动模拟
    在事件驱动的模拟系统中,需要按照事件的发生时间顺序来处理事件。使用大根堆可以有效地管理和调度这些事件。
    应用举例:
    离散事件模拟:如模拟交通流、制造过程等。
    计算机图形学:处理动画中事件的时间调度。

大跟堆的代码实现

插入操作:
插入新元素时,将元素添加到数组的末尾(完全二叉树的最后一个位置),然后进行“上浮”操作(也称为堆化)以恢复堆的性质。
上浮操作:
将新元素与其父节点比较,如果大于父节点,则交换位置,继续向上比较,直到元素小于或等于父节点,或者到达根节点。

public void insert(int key) {
    if (size == capacity) {
        throw new RuntimeException("Heap is full");
    }

    heap[size] = key; // 将新元素放在堆尾
    int current = size;
    size++;

    // 上浮操作
    while (current != 0 && heap[parent(current)] < heap[current]) {
        swap(parent(current), current);
        current = parent(current);
    }
}

2.删除最大值操作:
删除最大值(根节点)时,将数组的最后一个元素移动到根节点位置,然后进行“下沉”操作(也称为堆化)以恢复堆的性质。
下沉操作:
将根节点与其左右子节点比较,如果小于其中一个子节点,则与较大的子节点交换位置,继续向下比较,直到元素大于或等于子节点,或者到达叶节点。

public int extractMax() {
    if (size <= 0) {
        throw new RuntimeException("Heap is empty");
    }

    int root = heap[0]; // 保存根节点
    heap[0] = heap[size - 1]; // 将最后一个元素移到根节点位置
    size--;

    // 下沉操作
    maxHeapify(0);

    return root;
}

private void maxHeapify(int i) {
    int largest = i;
    int left = leftChild(i);
    int right = rightChild(i);

    if (left < size && heap[left] > heap[largest]) {
        largest = left;
    }

    if (right < size && heap[right] > heap[largest]) {
        largest = right;
    }

    if (largest != i) {
        swap(i, largest);
        maxHeapify(largest);
    }
}

3.交换元素:
在堆的操作过程中,经常需要交换两个节点的位置。

private void swap(int i, int j) {
    int temp = heap[i];
    heap[i] = heap[j];
    heap[j] = temp;
}

4.完整的大根堆实现
以下是大根堆的完整实现,包括构造函数、插入操作、删除最大值操作和辅助方法。

public class MaxHeap {
    private int[] heap;
    private int size;
    private int capacity;

    // 构造函数
    public MaxHeap(int capacity) {
        this.capacity = capacity;
        this.heap = new int[capacity];
        this.size = 0;
    }

    // 获取父节点索引
    private int parent(int i) { return (i - 1) / 2; }

    // 获取左子节点索引
    private int leftChild(int i) { return 2 * i + 1; }

    // 获取右子节点索引
    private int rightChild(int i) { return 2 * i + 2; }

    // 插入新元素
    public void insert(int key) {
        if (size == capacity) {
            throw new RuntimeException("Heap is full");
        }

        heap[size] = key; // 将新元素放在堆尾
        int current = size;
        size++;

        // 上浮操作
        while (current != 0 && heap[parent(current)] < heap[current]) {
            swap(parent(current), current);
            current = parent(current);
        }
    }

    // 提取最大元素(根节点)
    public int extractMax() {
        if (size <= 0) {
            throw new RuntimeException("Heap is empty");
        }

        int root = heap[0]; // 保存根节点
        heap[0] = heap[size - 1]; // 将最后一个元素移到根节点位置
        size--;

        // 下沉操作
        maxHeapify(0);

        return root;
    }

    // 下沉操作
    private void maxHeapify(int i) {
        int largest = i;
        int left = leftChild(i);
        int right = rightChild(i);

        if (left < size && heap[left] > heap[largest]) {
            largest = left;
        }

        if (right < size && heap[right] > heap[largest]) {
            largest = right;
        }

        if (largest != i) {
            swap(i, largest);
            maxHeapify(largest);
        }
    }

    // 交换元素
    private void swap(int i, int j) {
        int temp = heap[i];
        heap[i] = heap[j];
        heap[j] = temp;
    }

    // 主函数示例
    public static void main(String[] args) {
        MaxHeap maxHeap = new MaxHeap(10);
        maxHeap.insert(3);
        maxHeap.insert(1);
        maxHeap.insert(4);
        maxHeap.insert(1);
        maxHeap.insert(5);
        maxHeap.insert(9);
        maxHeap.insert(2);
        maxHeap.insert(6);
        maxHeap.insert(5);

        System.out.println("Extracted max: " + maxHeap.extractMax());
        System.out.println("Extracted max: " + maxHeap.extractMax());
        System.out.println("Extracted max: " + maxHeap.extractMax());
    }
}

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

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

相关文章

Web Server项目实战4-服务器编程基本框架和2种高效的事件处理模式

服务器编程基本框架 虽然服务器程序种类繁多&#xff0c;但其基本框架都一样&#xff0c;不同之处在于逻辑处理 模块功能I/O处理单元处理客户连接&#xff0c;读写网络数据逻辑单元业务进程或线程网络存储单元数据库、文件或缓存请求队列各单元之间的通信方式 I/O 处理单元是…

520主题趣味小游戏玩法线上互动的作用是什么

行业商家借势520气氛&#xff0c;往往能低成本达到预期效果&#xff0c;包括但不限于品牌传播、渠道引流涨粉、用户促活引导等&#xff0c;除了前面推荐的互动玩法外&#xff0c;在【雨科】平台的这几款520趣味小游戏同样值得关注。 1、爱你不止520 这是一款九宫格抽奖活动&am…

【Java面试】三、Redis篇(下)

文章目录 1、抢券场景2、Redis分布式锁3、Redisson实现分布式锁4、Redisson实现的分布式锁是可重入锁5、Redisson实现分布式锁下的主从一致性6、面试 1、抢券场景 正常思路&#xff1a; 代码实现&#xff1a; 比如优惠券数量为1。正常情况下&#xff1a;用户A的请求过来&a…

利用神经网络学习语言(六)——总结与常见面试问题

相关说明 这篇文章的大部分内容参考自我的新书《解构大语言模型&#xff1a;从线性回归到通用人工智能》&#xff0c;欢迎有兴趣的读者多多支持。 文章列表&#xff1a; 利用神经网络学习语言&#xff08;一&#xff09;——自然语言处理的基本要素利用神经网络学习语言&…

基于STM32看Cortex-M内核相关的一些底层知识

文章目录 固件起始地址存储了主栈指针和向量表内容启动文件分析程序启动流程Code,RO Data,RW Data, ZI Data启动流程Regin$$Table 固件起始地址存储了主栈指针和向量表内容 《ARM Cortex-M3与Cortex-M4权威指南》中的4.8章节复位和复位流程中有下面这段的描述&#xff1a; 在复…

医疗软件供应链安全治理:保障医疗服务质量和患者安全的当务之急!

如今&#xff0c;随着医疗数智化的不断深入&#xff0c;医共体网络、远程医疗网络、区域医疗网络、互联网医院等系统建设日益普及&#xff0c;医疗信息系统从基础应用进阶到智能医疗阶段。医疗机构对医疗软件采购、外包开发以及调用第三方开发资源的需求日益增加。 然而&#x…

buuctf的RSA(二)

1.RSA 知道 flag.enc 和 pub.key&#xff0c;典型的加密、解密 将pub,key 改为pub.txt 打开后发现公钥 在RSA公私钥分解 Exponent、Modulus&#xff0c;Rsa公私钥指数、系数(模数)分解--查错网 进行解密 得到e65537 n8693448229604811919066606200349480058890565…

S-Clustr+H4vdo 僵尸网络锁屏播放锁屏插件

项目地址:https://github.com/MartinxMax/S-Clustr-Ring 视频 用法 安装H4vdo依赖 在Install目录中选择你的操作系统安装依赖Windows_H4vdo_plugin_installation 启动H4vdo服务端 $ python3 Generate.py [Device Type (Number)]>7 [] [0] Start RTMP server [1] Skip &g…

家政预约小程序05服务管理

目录 1 设计数据源2 后台管理3 后端API4 调用API总结 家政预约小程序的核心是展示家政公司提供的各项服务的能力&#xff0c;比如房屋维护修缮&#xff0c;家电维修&#xff0c;育婴&#xff0c;日常保洁等。用户在选择家政服务的时候&#xff0c;价格&#xff0c;评价是影响用…

关于抖音小程序开发代码修改了,但是真机调试代码不更新问题解决(全网第一成功解决方案,无论安卓或苹果)

各位铁铁&#xff0c;今天开发小程序在抖音小程序适配时&#xff0c;终于是又一次踩到这个恶心的坑了&#xff0c;现在就记录一下&#xff0c;方便我以后查找&#xff0c;也希望帮助到当前被它所坑害的你&#xff01; 具体实现步骤如下&#xff1a; 1.到你的抖音开发平台&…

高效利用键盘上的 caps lock(大写键)实现中英切换

先看效果 在中文输入环境中&#xff0c;Caps Lock 键经常被忽视&#xff0c;占据了键盘上的黄金位置却很少派上用场。接下来&#xff0c;我将介绍如何将这个闲置的键合理利用&#xff0c;让它变得更加实用。 第一步 设置&#xff1a; 我以五笔为例&#xff1a; 1.输入法默认…

国内快速下载hugging face大模型的方法

由于众所周知的原因&#xff0c;从hugging face下载大模型比较困难&#xff0c;幸好国内有人做了镜像站&#xff0c;可以通过国内的镜像站进行快速下载&#xff0c;以下是配置方法。 我的系统是ubuntu 22&#xff0c;这里记录的方法只对debian/ubuntu有效。 git-lfs/INSTALLI…

精准安全运维,统信UOS服务器版V20(1070)漏洞修复指南丨年度更新

随着信息安全威胁的不断升级&#xff0c;操作系统的安全性已成为企业运维的关键要素。 为了确保业务运行环境的安全无忧&#xff0c;统信软件持续致力于技术创新和优化&#xff0c;并于日前重磅推出了统信UOS服务器版V20&#xff08;1070&#xff09;。该系统提供了高频补丁更…

将黑白图的白色部分叠加在彩色原图

彩色原图&#xff1a; 黑白图&#xff1a; 合成后&#xff1a; 代码&#xff1a; import cv2 import numpy as np# 读取原图和轮廓线条图 original_img cv2.imread(..\\IMGS\\pp.png) # 替换为原图路径 contour_img cv2.imread(..\\IMGS\\pp_edge.png, cv2.IMREAD_GRAYSCAL…

1 计算机硬件-CPU-校验码-存储系统-输入输出设备-总线结构

计算机硬件 考情分析&#xff1a;趋势很小&#xff0c;22年考过&#xff0c;根据趋势以后考的可能较小 基本组成&#xff1a;运算器&#xff0c;控制器&#xff0c;储存器&#xff0c;输入设备&#xff0c;输出设备运算器和控制器也统称为中央处理单元&#xff08;CPU&#xf…

flutter使用dbus插件时,在终端无法使用“dart-dbus”命令

不用flutter的人&#xff0c;可能都不会找到这儿&#xff0c;遇到这个问题&#xff0c;所以这里默认flutter已经装过了&#xff0c;且对flutter如何使用插件也有所了解了。 由于我在项目中用到了dbus插件&#xff0c;用法如图所示&#xff0c;我需要使用这条命令来生成一个sou…

多模态大模型新进展——GPT-4o、Project Astra关键技术丨青源Workshop第27期

青源Workshop丨No.27 多模态大模型新进展—GPT-4o、Project Astra关键技术主题闭门研讨会 刚刚过去的两天&#xff0c;OpenAI、Google纷纷发布了多模态大模型的最新成果&#xff0c;GPT-4o、Project Astra先后亮相。 本周五&#xff08;北京时间5月17日&#xff09;18点&#x…

supOS NEO科技普惠!永久免费!亿元补贴

数字化转型正在全球蓬勃发展&#xff0c;工业操作系统进入大规模推广期&#xff01; 如果您正在被预算不足、技术团队不强、数字化投入产出比等问题困扰&#xff0c;supOS NEO是您最好的选择。 “让supOS走进万千工厂、千行百业&#xff01;让全世界每个工厂都能用得上supOS&am…

Mysql与Navicat可视化命令大全 ----项目实战

软件准备&#xff1a;✍Mysql8.0下载地址&#xff08;推荐&#xff09;✍Navicat 16 下载地址&#xff08;推荐&#xff09; 注&#xff1a;不会安装看主页&#xff0c;关注我&#xff0c;免费指导&#xff0c;接计算机毕设☑ -----------------------------------------------…

尽在掌握:Android 13 通知新功能详解

尽在掌握&#xff1a;Android 13 通知新功能详解 在移动应用开发中&#xff0c;通知扮演着至关重要的角色&#xff0c;它如同应用程序与用户之间的桥梁&#xff0c;及时传递关键信息&#xff0c;提升用户体验。Android 13 作为最新的安卓版本&#xff0c;在通知方面带来了诸多…