【Java】还在死磕算法?懂“堆”与“优先级队列”,代码效率飙升

dc49951ad219454bbef81e408b809a6b.gif

欢迎 💛点赞 🌟收藏 💫关注


🏆堆

一、🎯堆的定义

堆的概念

堆是一种特殊的完全二叉树,它通过一维数组顺序存储关键码集合K={k0,k1,k2,...,kn-1},并遵循特定的顺序关系来定义。具体来说,若对于任意节点Ki,都满足Ki <= K2i+1 且 Ki <= K2i+2(或Ki >= K2i+2),则称这样的堆为小堆。堆分为两种类型:大根堆小根堆

  • 小根堆:根节点的值最小,父节点的值小于或等于其子节点的值;
  • 大根堆:根节点的值最大,父节点的值大于或等于其子节点的值;

c97ff782617443feb96aeb1f70a5c13e.png

堆的性质

  • 堆是一个完全二叉树;
  • 堆中任意节点的值总是不大于(或不小于)其父节点的值;

二、🀄️堆的构建

大堆

构建过程:
255b7fc12bd94eed89801a9e8ceccba9.png

ec55d38b93bd4e43a40ff20226edf8c7.png

代码实现:

public class Heap {
    public int[] elem; // 存储元素的数组
    public int usedSize; // 已使用的数组大小

    public Heap() {
        this.elem = new int[10];
    }

    // 初始化堆
    public void initHeap(int[] elem) {
        for (int i = 0; i < elem.length; i++) {
            this.elem[i] = elem[i];
            usedSize++;
        }
    }

    // 构建大堆,通过将父节点向下调整实现
    public void creatHeap() {
        for (int parent = (usedSize - 1) / 2; parent >= 0; parent--) {
            siftDown(parent, usedSize);
        }
    }

    public void siftDown(int parent, int usedSize) {
        int child = 2 * parent + 1;
        while (child < usedSize) {
            if (child + 1 < usedSize && elem[child] < elem[child + 1]) {
                child++;
            }
            if (elem[child] > elem[parent]) {
                swap(elem, child, parent);
                parent = child;
                child = 2 * parent + 1;
            } else {
                break;
            }
        }
    }

    private void swap(int[] elem, int i, int j) {
        int tmp = elem[i];
        elem[i] = elem[j];
        elem[j] = tmp;
    }
}

小堆

小堆的构建思路与大堆相似,区别在于父节点的值需要小于子节点的值。

代码实现:
```java
private void swap(int[] elem, int i, int j) {
int tmp = elem[i];
elem[i] = elem[j];
elem[j] = tmp;
}

public void creatHeap2() {
for (int parent = (usedSize - 1) / 2; parent >= 0; parent--) {
siftDown2(parent, usedSize);
}
}

public void siftDown2(int parent, int usedSize) {
int child = 2 * parent + 1;
while (child < usedSize) {
if (child + 1 < usedSize && elem[child] > elem[child + 1]) {
child++;

文章整理自互联网,只做测试使用。发布者:Lomu,转转请注明出处:https://www.it1024doc.com/4516.html

(0)
LomuLomu
上一篇 2024 年 12 月 27 日
下一篇 2024 年 12 月 27 日

相关推荐

  • 使用 gt-checksum 迁移表结构到 GreatSQL

    将数据库表结构迁移至 GreatSQL 的实践指南 引言 本文旨在指导用户如何利用 gt-checksum 工具,将数据库表结构从 ORACLE 平台平滑迁移至 GreatSQL。以下是详细的操作步骤和配置说明。 工具介绍:gt-checksum gt-checksum 是由 GreatSQL 社区开发的开源静态数据库校验与修复工具,广泛支持包括 MySQL…

    未分类 2024 年 12 月 27 日
    34300
  • 比想象中更复杂一点的MySQL Slow Query Log

    1. 问题概述 在分析 Slow Query Log 时,记录下的SQL语句,明明会对一张表执行全表扫描,可为什么慢日志中的 Rows_sent 、Rows_examined 和表的真实记录数也是不一样,甚至相差N多倍。还有一个细节就是上述的SQL语句,执行多次,在慢日志中记录下多条记录,记录之间Rows_sent 、Rows_examined也差别明显。 …

    未分类 2025 年 1 月 16 日
    30500
  • 多租户解析与Demo

    在做Saas应用时,多租户解析往往是很重要的组成部分,也是用户访问网站最先处理的逻辑。 文前介绍: 多租户的数据库实现方式主要有三种: 单一数据库实现,每条数据标识租户Id进行识别数据属于哪个租户 一租户一个数据库,能够做到完全的数据隔离 混合模式,部分数据在一张表上,主要是一些基础数据;其他业务数据分库存储。 无论是哪种方式都要知道租户是谁才能查询数据库。…

    2025 年 1 月 6 日
    26700
  • Java-异常处理机制-try-catch

    Java-异常处理机制 一、异常概述 1、异常的抛出机制 2、如何对待异常 3、异常的体系结构 3.1、Throwable 3.2、Error和Exception 3.3、编译时异常和运行时异常 3.4、常见的异常有哪些? 二、异常的处理方式一 try-catch的使用 1、过程1:抛 2、过程2:抓 3、使用细节 4、运行时异常案例 5、编译型异常案例 6…

    2025 年 1 月 6 日
    41600
  • 手动部署前后端分离的项目到本地

    1.准备工作 使用maven打包springboot项目为.jar文件得到springboot-0.0.1-SNAPSHOT.jar 打包vue项目 npm install -g @vue/cli安装Vue CLI 在项目根目录下,运行npm run build命令来构建项目得到一个dist文件夹 将打包好的文件通过远程仓库中转至docker虚拟机 在虚拟机…

    2025 年 1 月 11 日
    32500

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信