首页 > 其他分享 >洛谷题单指南-二叉堆与树状数组-P3378 【模板】堆

洛谷题单指南-二叉堆与树状数组-P3378 【模板】堆

时间:2024-11-05 12:41:29浏览次数:3  
标签:大根堆 P3378 int 洛谷题 元素 二叉 数组 节点 op

原题链接:https://www.luogu.com.cn/problem/P3378

题意解读:实现二叉堆。

解题思路:

二叉堆本质上一棵完全二叉树,根节点称为堆顶,根据特性不同分为有两种:

大根堆:所有父节点的值大于子节点,根节点最大

小根堆:所有父节点的值小于子节点,根节点最小

主要作用:动态维护序列,并快速找到最大/最小值,或者查找topN的值

主要操作:插入(O(logN))、查找最大/最小值(O(logN))、删除最大/最小值(O(logN))

存储方式:用数组来模拟完全二叉树int s[N],s[i]的左子结点为s[2 * i],右子节点为s[2 * i + 1],父节点为s[i / 2]

下面介绍三种主要操作:

设初始堆中有4个元素:2、3、4、5,且为大根堆

用数组存储为s[1] = 5, s[2] = 3, s[3] = 4, s[4] = 2

插入元素:

设插入元素6,先将6放置在数组末尾,即s[5] = 6,

然后进行向上比较,s[5]=6与s[2]=3比较,不符合大根堆性质,交换元素,此时s[2]=6,s[5]=3,

继续向上比较,s[2]=6与s[1]=5比较,依然不符合大根堆性质,交换元素,此时s[2]=5,s[1]=6

查找堆顶:

直接返回s[1]

删除堆顶:

先将堆顶和末尾元素进行交换,swap(s[1], s[5])

再从堆顶进行向下比较,先看s[1]=3和子节点s[2]=5,s[3]=4,s[2]更大,因此要交换swap(s[1], s[2])

再看s[2]=3和子节点s[4]=2,符合大根堆性质,不用交换

注意不用考虑s[5]=6的元素了,因为交换到末尾意味着将其删除,数组s的长度-1即可。

100分代码:

注意此题中,要用小根堆,判断的方式有所区别而已。

#include <bits/stdc++.h>
using namespace std;

const int N = 1000005;
int n, s[N], cnt;

void up(int p)
{
    if(p / 2 < 1) return;
    if(s[p] < s[p / 2])
    {
        swap(s[p], s[p / 2]);
        up(p / 2);
    } 
}

void down(int p)
{
    int left = p * 2;
    int right = p * 2 + 1;
    if(left > cnt) return;
    int minx = left;
    if(right <= cnt && s[right] < s[minx]) minx = right;
    if(s[minx] < s[p]) 
    {
        swap(s[minx], s[p]);
        down(minx);
    }
}

int main()
{
    cin >> n;
    int op, x;
    while(n--)
    {
        cin >> op;
        if(op == 1)
        {
            cin >> x;
            s[++cnt] = x;
            up(cnt);
        }
        else if(op == 2) cout << s[1] << endl;
        else if(op == 3)
        {
            swap(s[1], s[cnt]);
            cnt--;
            if(cnt) down(1);
        } 
    }
    return 0;
}

 

标签:大根堆,P3378,int,洛谷题,元素,二叉,数组,节点,op
From: https://www.cnblogs.com/jcwy/p/18527530

相关文章

  • leetcode107. 二叉树的层序遍历 II
    给你二叉树的根节点 root ,返回其节点值 自底向上的层序遍历 。(即按从叶子节点所在层到根节点所在的层,逐层从左向右遍历)示例1:输入:root=[3,9,20,null,null,15,7]输出:[[15,7],[9,20],[3]]示例2:输入:root=[1]输出:[[1]]示例3:输入:root=[]输出:[]提示:树......
  • 数据结构 ——— 计算链式二叉树叶子节点的个数以及计算链式二叉树的高度
    目录前言链式二叉树示意图​编辑手搓一个链式二叉树计算链式二叉树的叶子节点个数计算链式二叉树的高度 前言上一章学习了计算链式二叉树的节点个数数据结构———计算链式二叉树节点的个数-CSDN博客接下来学习的是计算链式二叉树叶子节点的个数以及计算链式二叉......
  • 二叉树的一些相关操作
    前言    链式结构二叉树的访问基本使用递归来进行访问,同时也可以体现出递归的暴力美学。因为有涉及到二叉树的相关操作,因此先要手动构造一个二叉树,在对其进行一些操作。        本篇一切对二叉树的操作都基于我创建的二叉树        这个是我构造的......
  • 二叉树的递归遍历(前、中、后序)
    二叉树的递归遍历题目链接:前序遍历:LeetCode144中序遍历:LeetCode94后序遍历:LeetCode145描述给你二叉树的根节点root,返回它节点值的前序、中序、后序遍历。示例1:前序遍历输入:root=[1,null,2,3]输出:[1,2,3]示例2:中序遍历输入:root=[1,null,......
  • 洛谷题单指南-字符串-P6824 「EZEC-4」可乐
    原题链接:https://www.luogu.com.cn/problem/P6824题意解读:已知整数序列a[i],i在1~n,有整数k,求一个整数x,要求a[i]^x<=k,使得符合要求的a[i]数量最多,求这个数量。解题思路:1、确定x的范围由于a[i]^x<=k,因此,x的有效二进制位不可能超过a[i],而a的取值范围<=1000000,因此x差不多......
  • 【笔记/模板】二叉搜索树-平衡树
    二叉搜索树www.luogu.com.cn定义二叉搜索树(\(\text{BinarySearchTree}\))是一种形状如二叉树的数据结构,用于快速查找和增加删除操作,它有如下几个特殊性质:空树是二叉搜索树。若二叉搜索树的左子树不为空,则其左子树上所有点的附加权值均小于其根节点的值。若二叉搜索树的右......
  • 数据结构 ——— 链式二叉树的前中后序遍历递归实现
    目录前言链式二叉树示意图​编辑手搓一个链式二叉树链式二叉树的前序遍历链式二叉树的中序遍历链式二叉树的后序遍历 前言在上一章学习了链式二叉树的前中后序遍历的解析数据结构———链式二叉树的前中后序遍历解析-CSDN博客接下来要学习的是代码实现链式二叉树......
  • 【数据结构】二叉树——堆
    一、二叉树的概念与结构二叉树的概念二叉树是树的一种,二叉树的特殊之处在于,每个根节点都可以有两个子节点,可以两个子节点都为空,或者一个为空,一个不为空,或者两个都有数,在构建二叉树的节点时就可以看出:现实中的二叉树:就像这颗树,每次分叉都分出两个枝条,这就是一个二叉树......
  • 二叉树进阶-二叉搜索树
    目录1.二叉树的概念2.二叉搜索树的操作2.1二叉搜索树的结构2.2实现节点的查找(find)2.3实现增加节点(insert)2.4实现删除节点(erase)2.5析构函数2.6二叉搜索树的完整实现3.二叉搜索树的应用3.1K模型3.2KV模型4.二叉搜索树的性能分析1.二叉树的概念二叉搜索树也叫二......
  • 代码随想录算法训练营第十五天|leetcode110. 平衡二叉树、leetcode257.二叉树的所有路
    1leetcode110.平衡二叉树题目链接:110.平衡二叉树-力扣(LeetCode)文章链接:代码随想录视频链接:后序遍历求高度,高度判断是否平衡|LeetCode:110.平衡二叉树_哔哩哔哩_bilibili1.1视频看后的思路1.1.1完整的代码就是不断判断,对其数据存储,其实突然发现每道题思路真的都很像,就......