从化手机网站建设商丘网络电视台

news/2025/9/23 9:54:41/文章来源:
从化手机网站建设,商丘网络电视台,秦皇岛网站建设服务,江西网站建设优化服务本文着重在于讲解用 “堆实现优先级队列” 以及优先级队列的应用#xff0c;在本文所举的例子中#xff0c;可能使用优先级队列来解并不是最优解法#xff0c;但是正如我所说的#xff1a;本文着重在于讲解“堆实现优先级队列” 堆实现优先级队列 堆的主要应用有两个… 本文着重在于讲解用 “堆实现优先级队列” 以及优先级队列的应用在本文所举的例子中可能使用优先级队列来解并不是最优解法但是正如我所说的本文着重在于讲解“堆实现优先级队列” 堆实现优先级队列 堆的主要应用有两个一个是排序方法[堆排序]一个是数据结构 [优先级队列]。 我们会发现人们总是把二叉堆画成一棵二叉树。其实二叉堆在逻辑上就是一种特殊的二叉树只不过存储在数组里。 比如 arr 是一个字符数组注意数组的第一个索引 0 空着不用 为什么索引 0 空着不用  为了方便计算父节点和子节点的索引通常会将数组的第一个元素存储在索引1的位置上而不是索引0。这样可以通过简单的数学计算得到父节点和子节点的索引而无需进行额外的操作。 具体来说在该代码中 根据完全二叉树的性质如果某个节点的索引为i则其左子节点的索引为2i右子节点的索引为2i 1。 如果索引从1开始则根节点的索引为1其左子节点的索引为2右子节点的索引为3。 如果索引从0开始则根节点的索引为0其左子节点的索引为1右子节点的索引为2。 因此为了避免对索引的调整和计算通常会将数组的第一个元素放在索引1的位置上并从索引1开始使用。这也是为什么在这段代码中索引0不被使用的原因。 请注意这种索引方式只是约定俗成的一种做法并非固定规定。在某些情况下也可以使用索引从0开始的方式实现堆或优先队列。这取决于具体的实现和需求。 构建优先级队列 可以使用 最大堆/最小堆 来构建优先级队列当插入或者删除元素的时候元素会自动排序这底层的原理就是二叉堆的操作。 当我们使用一个最大堆来实现一个优先级队列时堆顶元素总是数组中的最大值。这背后就是由[上浮] 和 [下沉] 两个操作来维护堆结构的。 维护堆结构的操作——swim和sink 我们要讲的是最大堆每个节点都比它的两个子节点大但是在插入元素和删除元素时难免破坏堆的性质这就需要通过这两个操作来恢复堆的性质了。 对于最大堆会破坏堆性质的有两种情况 1、如果某个节点 A 比它的子节点中的一个小那么 A 就不配做父节点应该下去下面那个更大的节点上来做父节点这就是对 A 进行下沉。 2、如果某个节点 A 比它的父节点大那么 A 不应该做子节点应该把父节点换下来自己去做父节点这就是对 A 的上浮。 当然错位的节点 A 可能要上浮或下沉很多次才能到达正确的位置恢复堆的性质。所以代码中肯定有一个 while 循环。 上浮操作的实现 private void swim(int x) {// 索引 1 是堆顶//判断x不是堆顶元素且x大于其父结点while (x 1 less(parent(x), x)) {// 交换x的父结点与x下标元素swap(parent(x), x);//将父节点的索引给x指针指向xx parent(x);}} 下沉操作的实现  private void sink(int x) {// size 是堆的最后一个索引//判断当x的左节点不是堆底元素时while (left(x) size) {// 先假设左边节点较大int max left(x);// 如果右边节点存在比一下大小//判断右节点不是堆底元素且右节点值大于max的值if (right(x) size less(max, right(x)))max right(x);// 结点 x 比俩孩子都大就不必下沉了if (less(max, x)) break;// 否则不符合最大堆的结构下沉 x 结点swap(x, max);x max;}} 数据结构的基本操作——增删查改  增加操作 将元素插到堆的底部然后上浮到对应位置 public void insert(Key e) {size;// 先把新元素加到最后pq[size] e;// 然后让它上浮到正确的位置swim(size);} 删除操作 将要删除的元素与堆底元素对调然后删除堆底元素。最后维护堆结构 public Key delMax() {// 最大堆的堆顶就是最大元素Key max pq[1];// 把这个最大元素换到最后删除之swap(1, size);pq[size] null;size--;// 让 pq[1] 下沉到正确位置sink(1);return max;} 查看操作 查看最大值直接返回堆顶元素即可 public Key max() {return pq[1];} 整体代码 public class MaxPQKey extends ComparableKey {/*完全二叉树中的索引下标是可以计算出来的*/// 父节点的索引int parent(int root) {return root / 2;}// 左孩子的索引int left(int root) {return root * 2;}// 右孩子的索引int right(int root) {return root * 2 1;}// 存储元素的数组private Key[] pq;// 当前 Priority Queue 中的元素个数private int size 0;public MaxPQ(int cap) {// 索引 0 不用所以多分配一个空间pq (Key[]) new Comparable[cap 1];}/* 返回当前队列中最大元素 */public Key max() {return pq[1];}/* 插入元素 e */public void insert(Key e) {size;// 先把新元素加到最后pq[size] e;// 然后让它上浮到正确的位置swim(size);}/* 删除并返回当前队列中最大元素 */public Key delMax() {// 最大堆的堆顶就是最大元素Key max pq[1];// 把这个最大元素换到最后删除之swap(1, size);pq[size] null;size--;// 让 pq[1] 下沉到正确位置sink(1);return max;}/* 上浮第 x 个元素以维护最大堆性质 */private void swim(int x) {// 如果浮到堆顶就不能再上浮了//因为是从索引1开始的所以索引1是堆顶//判断当x不是堆顶且x的父结点小于x时while (x 1 less(parent(x), x)) {// 如果第 x 个元素比上层大// 交换数组下标元素swap(parent(x), x);x parent(x);}}/* 下沉第 x 个元素以维护最大堆性质 */private void sink(int x) {// 如果沉到堆底就沉不下去了while (left(x) size) {// 先假设左边节点较大int max left(x);// 如果右边节点存在比一下大小if (right(x) size less(max, right(x)))max right(x);// 结点 x 比俩孩子都大就不必下沉了if (less(max, x)) break;// 否则不符合最大堆的结构下沉 x 结点swap(x, max);x max;}}/* 交换数组的两个元素 */private void swap(int i, int j) {Key temp pq[i];pq[i] pq[j];pq[j] temp;}/* pq[i] 是否比 pq[j] 小 */private boolean less(int i, int j) {return pq[i].compareTo(pq[j]) 0;} }附注1对Key extends ComparableKey的解释 Key extends ComparableKey是Java的泛型语法。它指示了MaxPQ类使用一个类型参数Key并且要求这个类型Key必须实现了ComparableKey接口。         ComparableKey接口是Java中定义的一个泛型接口用于比较两个对象的顺序。它要求实现类具有比较自身与其他对象的能力并返回一个整数值表示它们的相对顺序。         通过实现Comparable接口我们可以在堆和优先级队列中比较元素的大小以维护它们的排序规则。         在这段代码中Key作为泛型参数限制了存储在pq数组中的元素类型必须实现Comparable接口以便能够进行比较操作例如使用compareTo方法。这样做可以确保我们能够正确地进行插入、删除和获取最大元素等操作使得堆和优先级队列能够按照特定的顺序进行排序和处理。 附注2对“pq (Key[]) new Comparable[cap 1]”的解释 在这段代码中pq (Key[]) new Comparable[cap 1];是用来创建一个泛型数组的操作。         首先我们需要了解在Java中创建泛型数组的限制。由于Java的类型擦除机制无法直接创建一个具体类型的泛型数组。         因此我们只能通过创建一个非泛型数组然后将其转换为泛型数组。         在这段代码中new Comparable[cap 1]创建了一个长度为cap 1的非泛型数组         并且元素的类型是Comparable接口。这个数组在内存中被分配了空间。         然后(Key[])表示进行了一个类型转换。         因为我们知道该数组是要存储Key类型的元素所以我们将其强制转换为泛型数组类型Key[]。         最后将转换后的泛型数组赋值给变量pq使得pq引用这个泛型数组。         需要注意的是在进行强制类型转换时存在一定的风险。         如果实际存储在数组中的元素类型不符合泛型参数Key的约束条件可能会导致运行时错误。         因此在使用该代码时应确保泛型参数和实际存储的元素类型是匹配的。*/ 优先级队列的应用 力扣215. 数组中的第K个最大元素 思路 使用数组构造一个最大堆然后选出第k大的元素 构建最大堆 // 构建最大堆public void buildMaxHeap(int[] a, int heapSize) {for (int i heapSize / 2; i 0; --i) {maxHeapify(a, i, heapSize); // 对每个非叶子节点进行调整使其满足最大堆的性质}}// 调整以i为根节点的子树使其满足最大堆的性质public void maxHeapify(int[] a, int i, int heapSize) {//计算左右节点的下标int left i * 2 1, right i * 2 2, largest i;// 下沉操作比较节点i与其左右子节点的值找到最大值// 先与左节点对比if (left heapSize a[left] a[largest]) {largest left;}// 再与右节点对比if (right heapSize a[right] a[largest]) {largest right;}if (largest ! i) {swap(a, i, largest); // 将节点i与最大值节点交换位置maxHeapify(a, largest, heapSize); // 继续向下调整以保持最大堆的性质}}// 交换数组中两个元素的位置public void swap(int[] a, int i, int j) {int temp a[i];a[i] a[j];a[j] temp;} 问题1 “for (int i heapSize / 2; i 0; --i)”是什么意思 在构建最大堆时我们只需要对非叶子节点进行调整而不需要对叶子节点进行调整。这是因为堆的性质决定了一个完全二叉树的叶子节点已经满足最大堆的条件即叶子节点的值不会比其父节点更大。 考虑到完全二叉树的特点具有n/2个节点是非叶子节点其中n是堆中元素的总数。比如下标为i的元素其左节点为 2i右节点为 2i1所以对n个节点来说只能有n/2个节点是非叶子节点。 所以我们可以从最后一个非叶子节点索引为n/2 - 1开始向前逐个调用maxHeapify方法将每个节点及其子树调整为最大堆。 由于最大堆的性质要求父节点的值大于或等于其子节点的值通过逐层向上调整非叶子节点我们能够确保整个堆都满足最大堆的要求。 因此在buildMaxHeap方法中我们只对非叶子节点进行调整以节省时间 选出第k大的元素 选出第k大的元素的方法是取出堆顶的元素将其与堆底元素交换然后缩小堆重新维护堆结构。就相当于把堆顶的最大元素删除了。 正数第k个元素就是倒数的第 length - k 1个元素所以我们将后面length - k 1个元素与堆顶元素交换即可 public int findKthLargest(int[] nums, int k) {int heapSize nums.length;buildMaxHeap(nums, heapSize); // 构建最大堆for (int i nums.length - 1; i nums.length - k 1; --i) {swap(nums, 0, i); // 将堆顶元素与当前未排序部分的最后一个元素交换--heapSize; // 缩小堆的大小maxHeapify(nums, 0, heapSize); // 调整堆使其继续满足最大堆的性质}return nums[0]; // 返回第k个最大元素堆顶元素} 整体代码 class Solution {public int findKthLargest(int[] nums, int k) {int heapSize nums.length;buildMaxHeap(nums, heapSize); // 构建最大堆for (int i nums.length - 1; i nums.length - k 1; --i) {swap(nums, 0, i); // 将堆顶元素与当前未排序部分的最后一个元素交换--heapSize; // 缩小堆的大小maxHeapify(nums, 0, heapSize); // 调整堆使其继续满足最大堆的性质}return nums[0]; // 返回第k个最大元素堆顶元素}// 构建最大堆public void buildMaxHeap(int[] a, int heapSize) {for (int i heapSize / 2; i 0; --i) {maxHeapify(a, i, heapSize); // 对每个非叶子节点进行调整使其满足最大堆的性质}}// 调整以i为根节点的子树使其满足最大堆的性质public void maxHeapify(int[] a, int i, int heapSize) {//计算左右节点的下标int left i * 2 1, right i * 2 2, largest i;// 下沉操作比较节点i与其左右子节点的值找到最大值// 先与左节点对比if (left heapSize a[left] a[largest]) {largest left;}// 再与右节点对比if (right heapSize a[right] a[largest]) {largest right;}if (largest ! i) {swap(a, i, largest); // 将节点i与最大值节点交换位置maxHeapify(a, largest, heapSize); // 继续向下调整以保持最大堆的性质}}// 交换数组中两个元素的位置public void swap(int[] a, int i, int j) {int temp a[i];a[i] a[j];a[j] temp;} } 力扣347. 前 K 个高频元素 使用哈希表记录每个元素与其出现次数的映射关系 构建一个大小为k的小根堆如果不足k个元素就直接将当前数字加入到堆中 否则判断堆中的最小值是否小于当前数字的出现次数如果堆中的最小值小于当前数字出现次数说明目前的堆顶元素不在前k个高频元素中将其弹出并将当前数字加入到堆中 import java.util.*;class Solution {public int[] topKFrequent(int[] nums, int k) {// 统计每个数字出现的次数MapInteger, Integer counter new HashMap();for (int num : nums) {counter.put(num, counter.getOrDefault(num, 0) 1);}// 定义小根堆根据数字频率自小到大排序QueueInteger pq new PriorityQueue((v1, v2) - counter.get(v1) - counter.get(v2));// 遍历数组维护一个大小为 k 的小根堆// 不足 k 个直接将当前数字加入到堆中否则判断堆中的最小次数是否小于当前数字的出现次数// 若是则删掉堆中出现次数最少的一个数字将当前数字加入堆中。for (int num : counter.keySet()) {if (pq.size() k) {pq.offer(num);} else if (counter.get(pq.peek()) counter.get(num)) {pq.poll();pq.offer(num);}}// 构造返回结果int[] res new int[k];int idx 0;for (int num : pq) {res[idx] num;}return res;} }

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

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

相关文章

网站开发制作阶段的说课稿水发规划设计有限公司

一、 软件平台与硬件平台 软件平台: 1、操作系统:Windows-8.1 2、开发套件:ISE14.7 3、仿真工具:ModelSim-10.4-SE 硬件平台: 1、FPGA型号:XC6SLX45-2CSG324 二、 原理介绍 我的开发板上有4个LED灯&#xf…

制作微信网站免费装修设计效果图

5. Morphology_3.cpp 提取图像中水平线和垂直线的opencv示例 原图notes.png 灰度化 二值化 提取水平线 提取垂直线 对垂直图像取反 提取边缘 使用膨胀操作处理边缘 平滑处理:vertical.copyTo(smooth); blur(smooth, smooth, Size(2, 2)); smooth.copyTo(vertical, e…

如何给网站做证书沈阳城乡建设官方网站

文章目录 方案1 nohup &方案2 screen 方案1 nohup & 1、单独使用 nohup 执行脚本,如下图所示,终端会被接管,就是标准输入stdin 被关闭了,使用ctrlc会导致终止执行,但是可以关闭这个终端,重新打开终…

怎么样做网站赚钱东莞凤岗

linux 怎么写java一、环境安装由于使用 yum 或者 apt-get 命令 安装 openjdk 可能存在类库不全,从而导致用户在安装后运行相关工具时可能报错的问题,所以此处我们推荐采用手动解压安装的方式来安装 JDK。具体步骤如下:1.下载 JDK进入Oracle官…

Git仓库ssh不同环境配置

1.生成公私钥 ssh-keygen -t ed25519 -C "xx@163.com" -f ~/.ssh/id_ed25519_work 一直回车即可,完成后会生成这个打印的字符图2.生成之后会保存到c/Users/PC/.ssh文件夹下 3.重复上面的步骤生成多个公私…

超大附件怎么发送的高效解决方案与技巧

在日常办公中,处理大文件的需求越来越普遍,但超大附件怎么发送一直是个令人头痛的问题。许多用户因电子邮件服务的附件限制而不得不寻找其他方案。例如,Ftrans Outlook超大附件插件就成为了众多企业的首选工具,因为…

dm sql 缓存区

SQL缓冲区提供在执行SQL语句过程中所需要的内存,包括计划、SQL语句和结果集缓存。很多应用当中都存在反复执行相同SQL语句的情况,此时可以使用缓冲区保存这些语句和它们的执行计划,这就是计划重用。 查看现有设置 S…

网站建设项目表商标注册网上查询网

单元测试目的和意义 对于非正式的软件(其特点是功能比较少,后续也不有新特性加入,不用负责维护),我们可以使用debug单步执行,内存修改,检查对应的观测点是否符合要求来进行单元测试&#xff0c…

给国外传输大文件的最佳策略与解决方案

随着全球化的发展,给国外传输大文件的需求不断增加。企业在进行数据跨境传输时,可能会遇到法律合规性、网络速度和安全性等多重挑战。为了确保高效可靠的文件传输,企业可以了解并应用Ftrans飞驰云联数据跨境传输管控…

网站注销流程wordpress保护原创

文章目录1. 题目2. 解题2.1 递归2.2 BFS1. 题目 设计一个算法,可以将 N 叉树编码为二叉树,并能将该二叉树解码为原 N 叉树。 一个 N 叉树是指每个节点都有不超过 N 个孩子节点的有根树。 类似地,一个二叉树是指每个节点都有不超过 2 个孩子节…

学校网站的建设目标wordpress淘宝客跳转

解决图论问题中的最短路径问题一般有四种算法,分别是Floyd算法、Dijkstra算法、Bellman-Ford算法和SPFA算法,下面介绍一下这几种算法的模板和原理用途。 Floyd算法 原理:Floyd本质上是一个动态规划的思想,每一次循环更新经过前k…

网站内页是什么十堰的网络优化公司

93 复原IP地址 给定一个只包含数字的字符串 s ,用以表示一个 IP 地址,返回所有可能的有效 IP 地址,这些地址可以通过在 s 中插入 ‘.’ 来形成。你 不能 重新排序或删除 s 中的任何数字。你可以按 任何 顺序返回答案。 有效 IP 地址 正好由…

申请网站建设的请示学动漫制作专业后悔吗

题目还好。只是第一题题目错了,第二题真的难 今日分数 Rankperson分数1xxy2302蒟蒻2004xjq1805zyc17017hjq7519hzb2026lw1026lrz10 正题 T1:jzoj4024-石子游戏【SG函数,博弈论】 博客链接:https://blog.csdn.net/mr_wuyongcong/article/d…

怎么在手机上做微电影网站昆明网站建设哪家比较

Eureka是Netflix开发的服务发现组件,它能够实现服务注册、注销、健康检查,服务发现等功能,是Spring Cloud中常用的服务发现工具。Eureka Server与Eureka Client之间采用心跳机制,进行健康检查,每30秒发送一个心跳&…

做演讲视频的网站上海网站建设 s

AndroidStudio 2024 Win10/11最新安装配置 教程目的: (从安装到卸载) ,针对Kotlin开发配置,gradle-8.2-src/bin下载慢,以及Kotlin构建慢的解决 好久没玩AS了,下载发现装个AS很麻烦,就觉得有必要出个教程了(就是记录一下:嘻嘻) 因…

云南能投基础设施投资开发建设有限公司网站建设网站技术公司电话

一、环境搭建 1、安装pythonpycharm软件 。python安装网址官网:About Python™ | Python.org 根据自己的电脑系统选择最新版本 下载到本地,选择安装路径并配置好环境变量 验证安装是否成功 搜索中录入cmd 打开命令窗口 录入python显示一下版本号表示…

做网站买二手域名深圳市企业网站建设

Wannafly挑战赛24 题目连接 https://www.nowcoder.com/acm/contest/186#question A.石子游戏 题解 注意到当石子个数为偶数的时候,每回合都会减少一堆偶数石子,因此,先手必胜. 我们可以不考虑奇数堆石子,因为必胜方始终可以动偶数堆. 当必败方将奇数堆分成一堆偶数和一堆…

idea mvn package 报错java head space/ java.lang.OutOfMemoryError: Java heap space

近期更换电脑,重新安装idea环境后,首次 mvn package 报错java heap space 。 使用mvn -X package 发现是Xmx8196 需要使用64位 open JDK 才可以支持 所以使用cmd 查看旧电脑和新电脑 java version 新电脑不是64位…

湖南网站建设磐石网络答疑室内设计小白怎么入行

模板模式是类的行为模式。准备一个抽象类,将部分逻辑以具体方法以及具体构造函数的形式实现,然后声明一些抽象方法来迫使子类实现剩余的逻辑。不同的子类可以以不同的方式实现这些抽象方法,从而对剩余的逻辑有不同的实现。这就是模板方法模式…

大环境不好,这几个赚钱网站可以试试

广告Google Adsense - Google 的展示广告网络,可帮助网站进行流量变现。 万维广告 - 更简单优雅的广告网络,帮助技术文档/开源社区等技术站点投放强相关的云服务广告,获取可观收入。 穿山甲 - 帮助 APP 开发者进行流…