堆 优先队列

SGI STL:heap排序的adjust函数 SGI STL:heap排序中adjust函数 本文不介绍具体的heap排序算法,阅读之前请先熟悉STL heap排序的逻辑。本文讨论的是SGI-STL源码中__adjust_heap函数中的一个细节。先展示源码。 // 实际执行的push函数: template <class _RandomAccessIterator, class _Distance, class _Tp> void __push_heap(_RandomAccessIterator __first, 阅读详情

  首先看完全二叉树的定义:

若设二叉树的深度为h,除第 h 层外,其它各层 (1~h-1) 的结点数都达到最大个数,第 h 层所有的结点都连续集中在最左边,这就是完全二叉树。

  如果一个完全二叉树的某个结点值都不大于或小于他的父结点,那就叫做堆。根结点是所有结点里最大的叫大根堆,最小的叫小根堆。

  比如:

 9-1 a是大根堆,9-2 a是小根堆,剩下的都不是堆(因为不是完全二叉树)。

  那么怎么样才能构造出堆呢?

把一棵树结点按顺序标号

从后往前找到第一个有孩子的结点(肯定在倒数第二排,最后一排已经是堆),看以这个结点为根结点的树满不满足堆的条件,如果不满足就和下面的交换,直到满足堆的条件。就这么一个一个结点检查,一直到根结点,堆就完成了~

  比如到结点4(大根堆),15比17小,17没孩子,所以只要把15和17换就行了,此时结点4是17,结点8是15,再到结点2的时候,因为12比17小,所以把17移动到结点2,12又比15小,所以把15移动到结点4,最后把12移动到结点8。

  为什么要从后往前呢?这是因为在检查一个结点的时候,如果以他孩子为根结点的树已经是堆,就只要找到这个点应该插入的位置,把子结点都往上移一个就行了~

小根堆代码:

void heapadjust(int i,int l)    //检查结点函数,i是这个结点的位置,l是堆的结点数,设根结点为0
{
    int child,t;
    for(t=a[i]; i*2+1<l; i=child)  //i*2+1是左孩子,t是检查的结点的值
    {
        child=i*2+1;    //  i是父结点
        if(child+1<l&&a[child+1]<a[child]) child++;  //如果右孩子比左孩子小(取最小的孩子)
        if(t>a[child]) a[i]=a[child];   //如果最小的孩子比t小,就把那个孩子的值给父结点
        else break; 
    }
    a[i]=t;   //此时已经找到该放的位置,插入t
}
void heapsort(int l)
{
    int i,temp;
    for(i=l/2-1; i>=0; i--) heapadjust(i,l);  //从第1个有孩子的结点开始找,一直到根结点
}

  大根堆只要把符号改一下就行了,方法是一样的~


void maxheap_add(int x){
    Lmax++;
    int child=Lmax,fa=child>>1;
    while(fa>0&&a[fa]<x){
        a[child]=a[fa];
        child=fa;
        fa>>=1;
    }
    a[child]=x;
}
void minheap_add(int x){
    Lmin++;
    int child=Lmin,fa=child>>1;
    while(fa>0&&b[fa]>x){
        b[child]=b[fa];
        child=fa;
        fa>>=1;
    }
    b[child]=x;
}
void maxheap_adjust(int x){
    int t=a[x],fa=x,child=fa<<1;
    while(child<=Lmax){
        if(child+1<=Lmax&&a[child+1]>a[child]) child++;
        if(t<a[child]){
            a[fa]=a[child];
            fa=child;
            child=fa<<1;
        }
        else break;
    }
    a[fa]=t;
}
void minheap_adjust(int x){
    int t=b[x],fa=x,child=fa<<1;
    while(child<=Lmin){
        if(child+1<=Lmin&&b[child+1]<b[child]) child++;
        if(t>b[child]){
            b[fa]=b[child];
            fa=child;
            child=fa<<1;
        }
        else break;
    }
    b[fa]=t;
}
int maxheap_del(){
    int t=a[1];
    a[1]=a[Lmax];
    Lmax--;
    maxheap_adjust(1);
    return t;
}
int minheap_del(){
    int t=b[1];
    b[1]=b[Lmin];
    Lmin--;
    minheap_adjust(1);
    return t;
}


  堆只能保证根结点最大或最小,其他元素并不一定是有序的,但只要每次把根结点和最后一个结点交换,再把剩下无序的结点调整成堆,再把根结点放到后面,再。。重复。。直到最后一个结点,就排完序了~

void heapsort(int l)
{
    int i,temp;
    for(i=l/2-1; i>=0; i--) heapadjust(i,l);
    for(i=l-1;i>0;i--){
    temp=a[0];             //交换最后一个和根结点
    a[0]=a[i];
    a[i]=temp;
    heapadjust(0,i);} //  这时除根结点,其他本来已经都是堆,只需检查根结点
}


  下面来说优先队列(也是刚发现这个东东。。原理就是堆吧),具体的我也说不好,就简单说下怎么用吧得意

  首先头文件里要有#include<queue>,

最小值优先:priority_queue<int,vector<int>,greater<int> >q;

最大值优先:priority_queue<int,vector<int>,less<int> >q;

  第一个int就是int类型的,vector<int>就是默认的什么=。=我也搞不懂,写上就行了。。委屈,greater是最小值优先,less是最大值优先。


顺便说一下STL队列(不是优先队列)

queue <int> q;

Push():入队,即插入元素

Pop():出队,即删除元素

Front():读取队首元素

Back():读取队尾元素

Empty():判断队列是否为空

Size():队列当前元素

杭电4006

The kth great number

Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65768/65768 K (Java/Others)
Total Submission(s): 4790 Accepted Submission(s): 1962


Problem Description
Xiao Ming and Xiao Bao are playing a simple Numbers game. In a round Xiao Ming can choose to write down a number, or ask Xiao Bao what the kth great number is. Because the number written by Xiao Ming is too much, Xiao Bao is feeling giddy. Now, try to help Xiao Bao.

Input
There are several test cases. For each test case, the first line of input contains two positive integer n, k. Then n lines follow. If Xiao Ming choose to write down a number, there will be an " I" followed by a number that Xiao Ming will write down. If Xiao Ming choose to ask Xiao Bao, there will be a "Q", then you need to output the kth great number.

Output
The output consists of one integer representing the largest number of islands that all lie on one line.

Sample Input
8 3 I 1 I 2 I 3 Q I 5 Q I 4 Q

Sample Output
1 2 3
Hint
Xiao Ming won't ask Xiao Bao the kth great number when the number of the written number is smaller than k. (1=<k<=n<=1000000).

  刚开始做的是插入元素后就堆排序,输出时就输出a[k],怎么都超时。。后来发现。。只要只在数组里保存k个,在开始构造成一个最小堆,再插入时只要比较要插入的元素和堆的根结点哪个大,如果它比根结点大,就用它代替根结点,这时因为底下的都已经是堆,所以只要调用那个检查结点函数检查根结点就行~(并不需要每次都排序,只要保证堆中k个元素都是目前最大的k个,输出时直接输出根结点就行了(k个最大的里面的最小的))。这道题用优先队列更简单~

最小堆:

#include<stdio.h>
int a[1000010];
void heapadjust(int i,int l)
{
    int child,t;
    for(t=a[i]; i*2+1<l; i=child)
    {
        child=i*2+1;
        if(child+1<l&&a[child+1]<a[child]) child++;
        if(t>a[child]) a[i]=a[child];
        else break;
    }
    a[i]=t;
}
void heapsort(int l)
{
    int i,temp;
    for(i=l/2-1; i>=0; i--) heapadjust(i,l);
}
int main()
{
    freopen("D:\\CodeBlocks\\file\\in.txt","r",stdin);
    int n,k,t;
    char s[5];
    while(scanf("%d%d",&n,&k)!=EOF)
    {
        int l=k,i;
        for(i=0; i<k; i++)
            scanf("%s%d",s,&a[i]);
        heapsort(k);
        n-=k;
        while(n--)
        {
            scanf("%s",s);
            if(s[0]=='I')
            {
                scanf("%d",&t);
                if(t>a[0])
                {
                    a[0]=t;
                    heapadjust(0,k);
                }
            }
            else
            {
                printf("%d\n",a[0]);
            }
        }
    }
    return 0;
}

优先队列:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
int main()
{
    freopen("D:\\CodeBlocks\\file\\in.txt","r",stdin);
    int n,k,t;
    char s[5];
    while(scanf("%d%d",&n,&k)!=EOF)
    {
        priority_queue<int,vector<int>,greater<int> >q;
        int i,t;
        for(i=0; i<n; i++)
        {
            scanf("%s",s);
            if(s[0]=='I')
            {
                scanf("%d",&t);
                if(q.size()<k) q.push(t);
                else
                {
                    q.push(t);
                    q.pop();
                }
            }
            else printf("%d\n",q.top());
        }
    }
    return 0;
}


C++实现优先队列——最小堆,d路堆及配对堆 C++实现三种优先队列 阅读详情

相关推荐

优先队列-堆

优先队列  队列是一个操作受限的线性表,数据只能在一端进入,另一端出来,具有先进先出的性质。有时在队列中需要处理优先级的情况,即后面进入的数据需要提前出来,这里就需要优先队列。优先队列是至少能够提供插入和删除最小值这两种操作的数据结构。对应于队列的操作,插入相当于入队,删除最小相当于出队。   链表,二叉查找树,都可以提供插入和删除最小这两种操作。对于链表的实现,插入需要O(1),删除最小需要遍历

三哥的博客 3856

堆排序

注释解释的完整堆排序代码 #include<iostream> #include<algorithm> using namespace std; //调整为大顶堆 //i这里是非叶子节点下标 void HeapAdjust(int arr[],int i,int len) { int temp = NULL;//temp这里用来保存可能会被替换掉的根节点,防止被替换掉之后,无法找回替换前的根节点 temp = arr[i];//保存当...

m0_53157173的博客 578

图解算法:堆、堆排序、优先队列

堆、堆排序、优先队列可以看成就是一个东西;堆是一种非常重要的数据结构,堆排序是基于堆这种数据结构实现的;优先队列可以用堆这种数据结构来实现,也可以用其他数据结构实现。优先队列可以用来实现有优先级的任务调用(一些任务在池子里等待,优先级最高的先被优先取出执行)

zfj321的博客 1427

堆排序(参考大话数据结构)

堆排序是一种非稳定的排序,属于选择排序类,它的核心是要构建一个大顶堆或者是小顶堆,以大顶堆为例,根节点的值为最大值,交换到数组的最后,然后对1至n-1的元素继续构建一个大顶堆,再将根节点与第n-1个元素交换,如此循环,直到最后数组为有序。         首先定义要用到的结构: #define MAXSIZE 10 typedef struct { int r[MAXSIZE +

henryhungry的专栏 862

堆——优先队列的实现

用数组表示的完全二叉树,堆是一种常用来实现优先队列的树形数据结构。堆通常以树形结构组织元素,但使用数组来存储这些元素。这种方法可以高效地管理完全二叉树的结构。以下是一个更详细的解释以及如何在C语言中实现这个概念。

码明的博客 931

YOLOv11多模态融合实战:基于YOLOFuse的RGB与红外线(IR)协同检测技术解析

本文深入解析了基于YOLOv11的YOLOFuse多模态融合技术,重点探讨了RGB与红外线(IR)协同检测的实现原理与实战应用。文章详细介绍了双流架构与数据级、特征级、决策级三种融合策略,并通过实战案例展示了其在低光照、复杂环境下显著提升检测精度与鲁棒性的优势,为全天候安防、自动驾驶等场景提供了有效的技术解决方案。

weixin_29041195的博客 649

优先队列和堆

什么是优先队列? 听这个名字就能知道,优先队列也是一种队列,只不过不同的是,优先队列的出队顺序是按照优先级来的;在有些情况下,可能需要找到元素集合中的最小或者最大元素,可以利用优先队列ADT(Abstract Data Type)来完成操作,优先队列ADT是一种数据结构,它支持插入和删除最小值操作(返回并删除最小元素)或删除最大值操作(返回并删除最大元素); 这些操作等价于队列的enQueue和deQueue操作,区别在于,对于优先队列,元素进入队列的顺序可能与其被操作的顺序不同,作业调度是优先队列的一个应

数据工匠记 1257

100道测试工程师笔试的Linux笔试题及答案_网络安全工程师关于linux的笔试大题

47.Linux系统中,一般把命令 ls 定义为 ls --color 的别名,以便以不同颜色来标识不同类型的文件。但是,如何能够使用原先的ls命令?83.在xdm的配置目录中,哪个文件用来设置在用户通过xdm登录后自动起动的应用程序?45.你的系统使用增量备份策略,当需要恢复系统时,你需要按什么顺序恢复备份数据?84.命令 netstat -a 停了很长时间没有响应,这可能是哪里的问题?51.Linux中,提供TCP/IP包过滤功能的软件叫什么?88.TCP/IP中,哪个协议是用来进行IP自动分配的?

2401_84247760的博客 1054

Python的堆与优先队列

Python的堆与优先队列 堆与优先队列 堆(英语:Heap)是计算机科学中的一种特别的树状数据结构。堆有如下特点:给定堆中任意节点P和C,若P是C的母节点,那么P的值会小于等于(或大于等于)C的值”。 按照母节点与子结点的大小关系,堆又可以分为以下两种:若母节点的值恒小于等于子节点的值,此堆称为最小堆(min heap);反之,若母节点的值恒大于等于子节点的值,此堆称为最大堆(max heap)。 在堆中最顶端的那一个节点,称作根节点(root node),根节点本身没有母节点(parent node)。

weixin_46302487的博客 767

【技术实践指南】Python解析FactSet Revere供应链数据:构建企业级断裂与重构监测指标

本文提供了一份企业级Python实践指南,详细解析如何利用FactSet Revere供应链数据库,构建供应链断裂与重构监测指标。内容涵盖数据清洗、关系对筛选、时间序列处理及核心指标(断裂、恢复、转移)的工程化实现,旨在帮助数据工程师与分析师搭建自动化、可解释的供应链风险监控系统。

weixin_29051811的博客 926

HC-05蓝牙模块详细配置、连接与使用过程

用手按着模块上的按键,再给蓝牙模块上电。当蓝牙模块上的灯慢闪的时候就说明进入了配置模式了。在配置蓝牙的时候一定要将串口助手按这个要求配置:设置波特率 38400,数据位 8 位,停止位 1 位,无校验位,这是固定操作! 根据蓝牙的主从模式进行不同的设置,二者主要区别就在于AT+ROLE这个指令如果这里没返回OK可能有一下几种情况:如果正常返回OK,那就可以进行下一步了 配置蓝牙密码的时候,特别是配置HC05,密码必须加双引号"",否则不能正常设置!!!! 给从机模式蓝牙配置好之后,将蓝牙重

qq_51688022的博客 2万+

Dijkstra算法堆/优先队列优化

Dijkstra算法堆/优先队列优化前言额外知识简介堆与优先队列STL库重载Dijkstra分析及优化分析优化代码实现存储结构边点优先队列函数初始化添加边Dijkstra主函数后记 前文:Dijkstra算法&&邻接表数组 前言 ​ 1、本文中所采用的存储结构依然是邻接表数组,只是较上一篇文章中的结构稍微发生了一些变化,但本质是一样的,若不懂可参考前文; ​ 2、本文将涉及到堆...

Mark-2000的博客 6815

Polyworks脚本开发学习笔记(十五)-用Python连接Polyworks的COM组件

Polyworks脚本开发学习笔记(十五)-利用Python连接Polyworks的COM组件

qq_43662503的博客 2499

堆、堆排序、优先队列

文章目录堆1 (二叉)堆2 二叉堆的两种形式3 维护堆的性质4 建堆5 堆排序6 优先队列6.1 最大值(MAXIMUMMAXIMUMMAXIMUM)6.2 返回并弹出最大值(EXTRACT−MAXEXTRACT-MAXEXTRACT−MAX)6.3 增大关键字(INCREASE−KEYINCREASE-KEYINCREASE−KEY)6.4 插入(INSERTINSERTINSERT)6.5 优...

qq_39378221的博客 616

【HOJ系列】HOJ判题机部署

【HOJ系列】HOJ判题机部署

随风浪仔的专栏 903

STM32开发 -- GPS模块开发详解

一、了解硬件 我使用的GPS模块型号为UBX-M8030 参看:UBX-M8030 系列 查看一下它的特性: 多用途 GNSS 芯片,提供三种产品等级 最多可并发接收 3 个 GNSS(GPS、伽利略、GLONASS、北斗) 行业领先的 -167 dBm 导航灵敏度 业界最低电流消耗 在城市峡谷中具有绝佳的定位精度 安全性和完整性保护 支持所有的卫星增强系统 车载级芯片的工作...

不积跬步,无以至千里 3万+

优先队列与堆

优先队列与堆 优先队列与堆 一 优先队列 1.1 定义 1.2 API 1.3 实现 二 堆 2.1 定义 2.2 表示 2.3 堆的有序化 2.4 基于堆的优先队列 一 优先队列 1.1 定义 在很多应用中,我们通常需要按照优先级情况对待处理对象进行处理,比如首先处理优先级最高的对象,然后处理次高的对象。最简单的一个例子就是,在手机上玩游戏的时候,如果有...

能能 1333

动力学约束下的运动规划算法——Kinodynamic RRT*算法

动力学约束下的运动规划算法——Kinodynamic RRT*算法

慕羽★的博客 6747

基于堆的优先队列实现

基于堆的优先队列实现 优先队列严格说实际上不是一种队列,因为它并不需要遵循队列的FIFO特性,而要求的基本操作包括:向队列中插入新的记录,以及移出队列中的最大的元素。我们可以以各种不同的方式来实现优先队列——只要能够满足上面的两个接口就可以了。但是基于堆的优先队列则具有较好的性能。 优先队列是一种很有用的数据结构,因为实际上我们不是每时每刻都需要对数据进行严格的排序,有时候我们仅仅...

banyi4389的博客 119

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

优先队列,堆

普通的数据结构,如果我们想要寻找所存元素中的最大值或者最小值,需要挨个查找。而本章所学的优先队列和堆会按照优先级给元素排序,帮助我们以最快的速度O(1)获取优先级最高的元素。 优先队列 优先队列把优先级最高的元素设为链表的头节点,这样我们获取或删除优先级最高的元素只需要O(1)的时间复杂度,这么设计的代价就是牺牲插入的效率,每次插入一个新的元素时,我们都需要迭代链表,并找到合适的地方插入,这个时间复杂度往往是O(n)。 以下是优先队列支持的操作: push:插入一个新的元素 pop:将优先级最高的元素弹出

weixin_38384296的博客 855

锂电池充电器电路设计 里面有电路

锂电池充电器电路设计 里面有电路 3.7V升压到5V电路设计。

用堆实现优先队列

 优先队列不同于普通队列采用先进先出的队列元素存取方式。插入队列元素时按照一定的规则插入,每次都是取队列中优先级最高的元素。可以采用最大堆来实现优先队列。堆是一颗完全二叉树,每个结点有一个权。它的特点是根结点的权值最大,且根的两个子树也各是一个堆。可以用数组来模拟堆。堆的操作有两种: (1)插入:方法是将新的元素i插到当前数组最后一个元素的下一个位置,然后对i进行上升调整。当i比它的父亲大

2532

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

优先队列(堆)

这里写自定义目录标题场景功能快捷键合理的创建标题,有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左、居右SmartyPants创建一个自定义列表如何创建一个注脚注释也是必不可少的KaTeX数学公式新的甘特图功能,丰富你的文章UML 图表FLowchart流程图导出与导入导出导入 #用堆实现优先队列 你好! 这是你第一次使用 Markdown编辑器 所展示的欢迎页。如果你想学习如何使用Markdown编辑器, 可以仔细阅读这篇文章,了解

qq_44234405的博客 1555

优先队列、最小堆、最大堆

其实排列顺序就是从上到下,从左到右进行排列,例如{1,2,3,4,5,6,7},看第一张图就是按照顺序进行排列,当然对照下面公式也可以来做,例如 1 的索引为0,要确定它的左子节点就是 0* 2 +1 = 1,也就是索引1,对应元素值2,同理右子节点就是 0*2+2=2,索引2也就是元素值3.这样,对于下标为i的节点,其左子节点的下标为2i,右子节点的下标为2i+1,而其父节点的下标为i/2。对应的数组为[10, 20, 15, 30, 40],符合小顶堆的定义,即每个节点的值都小于或等于其子节点的值。

m0_64132144的博客 997
上一篇: 离散化+树状数组 求逆序对数
下一篇: 字符串DP
小小小小葱
博客等级 码龄14年 22粉丝 266原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值