数据结构-堆详解

图片:

二叉堆的父节点为这个子树的最值。

如何维护它。
我们发现它是一棵二叉树,那就自然满足若父节点为 x x x 则左儿子节点为 x × 2 x\times2 x×2 右儿子为 x × 2 + 1 x\times 2 + 1 x×2+1 这是显然的,但如果写成指针或结构体就太麻烦了,所以考虑用数组来维护它。

用一个数组 T T T 来存储这颗二叉树,根节点为 T 1 T_1 T1 根据二叉树的性质对于每个子节点 x x x 则有:

  1. x > 1 x>1 x>1 则fa[x]=i/2;
  2. 2 × x > n 2\times x>n 2×x>n x x x 没有儿子,如果 2 × x + 1 > n 2\times x+1>n 2×x+1>n x x x 没有右儿子。
  3. 如果节点 x x x 有孩子,则 x x x 的左儿子为 x × 2 x\times 2 x×2 右儿子为 x × 2 + 1 x\times 2 + 1 x×2+1

复杂度分析:

这样做由于二叉树只有 log ⁡ 2 n \log_2n log2n 层,自然单次复杂度为 O ( log ⁡ 2 n ) O(\log_2n) O(log2n)可以解决 n ≤ 1 0 6 n\leq 10^6 n106 及以下的问题。

那么该如何让这个二叉树平衡?通常使用上浮法与下沉法。
例子:
假设你已经有一个堆了,就是上面那个

这个时候你如果想要给它加入一个节点怎么办,比如说0?

先插到堆底(严格意义上来说其实0是在5的左儿子的,图没画好放不下去,不过也不影响)

然后你会发现它比它的父亲小啊,那怎么办?不符合小根堆的性质了啊,那就交换一下他们的位置

交换之后还是发现不符合小根堆的性质,那么再换

还是不行,再换

好了,这下就符合小根堆的性质了。

事实上堆的插入就是把新的元素放到堆底,然后检查它是否符合堆的性质,如果符合就丢在那里了,如果不符合,那就和它的父亲交换一下,一直交换交换交换,直到符合堆的性质,那么就插入完成了。
删除同理这里不在复述了。

代码:

插入:

void push(int x){h[++len] =x;int i=len;while(i>1 && h[i]<h[len/2]){swap(h[i],h[i/2]);i/=2;}
}

删除:

void pop(){h[1] = h[len--];int i=1;while((i<<1)<=len){int son=(i<<1);if(son<len&&h[son+1]<h[son]){son++;}if(h[son]<h[i]){swap(h[son],h[i]);i=son;}else break;}
}

STL堆:

算法竞赛中虽然STL没有手写快但是否好像实用代码:

定义一个大根堆即堆内为递减的序列

priority_queue<int> Q;

小根堆:

priority_queue<int,vector<int>,greater<int>> Q2;

使用:

插入一个数:

void insert(int x){q.push(x);
}

删除堆头:

void erase(){q.pop();
}

访问堆头

int front(){return q.top();
}

建议使用STL的堆

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

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

相关文章

MacOS Docker 部署 Solr 搜索引擎

一、简介 Solr 是 Apache 下的一个顶级开源项目&#xff0c;采用 Java 开发&#xff0c;它是基于 Lucene 的全文搜索服务器。Solr 可以独立运行在 Jetty、Tomcat 等这些 Servlet 容器中。Solr 提供了比 Lucene 更为丰富的查询语言&#xff0c;同时实现了可配置、可扩展&#x…

免费使用Kimi的API接口,kimi-free-api真香

今年&#xff0c;随着各大GLM模型的开源和算力的提升&#xff0c;尤其是最近比较火热的月之暗面的Kimi 模型&#xff0c;AI应用场景中的各种智能体如雨后春笋般涌现。许多同学们纷纷表达了加入AI应用的学习和测试的愿望&#xff0c;然而各大模型提供商所提供的API的免费tokens在…

集群管理命令总结

前言 在进行TPC性能测试时用到两个集群管理命令&#xff1a;clush 和 pssh&#xff0c;这俩命令都可以在多台服务器上并发执行相同命令&#xff0c;其中个人比较推荐 clush&#xff0c;因为感觉 clush 比较好用&#xff0c;本文来总结一下 clush 和 pssh 的安装配置和使用。 …

读所罗门的密码笔记20_更好的自己

1. 民营部门 1.1. 障碍最大的一步&#xff0c;与履行协议所需要的人才和技能有关 1.2. 多样性很好&#xff0c;不要过分依赖任何一种资源&#xff0c;因为政府会出于政治原因淡化问题&#xff0c;不尊重科学&#xff0c;甚至退出协议 1.2.1. 民营部门和非政府组织的强大联盟…

在Mac中打开终端的3种方法

在使用Mac时&#xff0c;有时需要深入研究设置&#xff0c;或者完成一些开发人员级的命令行任务。为此&#xff0c;你需要终端应用程序来访问macOS上的命令行。下面是如何启动它。 如何使用聚焦搜索打开终端 也许打开终端最简单、最快的方法是通过聚焦搜索。要启动聚焦搜索&a…

算法1: 素数个数统计

统计n以内的素数个数 素数&#xff1a;只能被1和自身整除的自然数&#xff0c;0和1除外&#xff1b; 举例&#xff1a; 输入&#xff1a;100 输出&#xff1a;25 import java.util.*; class Test1{public static void main(String[] args){int a 100; //输入数字//…

rocketmq和rabbitmq总是分不清?

1. 官方解答 摘自百度搜索&#xff1a; 2. 通俗易懂的回答

CentOS7离线升级OpenSSH_8.8p1

一、环境 centos7.9,升级openssh到8.8p1最新版本 二、下载升级包 # openssl和zlib为相关依赖 wget https://cdn.openbsd.org/pub/OpenBSD/OpenSSH/portable/openssh-8.8p1.tar.gz wget https://www.openssl.org/source/openssl-1.1.1j.tar.gz wget http://www.zlib.net/zl…

C语言之offsetof实现分析(九十一)

简介&#xff1a; CSDN博客专家&#xff0c;专注Android/Linux系统&#xff0c;分享多mic语音方案、音视频、编解码等技术&#xff0c;与大家一起成长&#xff01; 优质专栏&#xff1a;Audio工程师进阶系列【原创干货持续更新中……】&#x1f680; 优质专栏&#xff1a;多媒…

计算机网络——实现smtp和pop3邮件客户端

实验目的 运用各种编程语言实现基于 smtp 协议的 Email 客户端软件。 实验内容 1. 选择合适的编程语言编程实现基于 smtp 协议的 Email 客户端软件。 2. 安装 Email 服务器或选择已有的 Email 服务器&#xff0c;验证自己的 Email 客户端软件是否能进行正常的 Email 收发功…

【web网页制作】html+css旅游家乡山西主题网页制作(3页面)【附源码】

山西旅游网页目录 涉及知识写在前面一、网页主题二、网页效果Page1、景点介绍Page2、酒店精选|出行攻略Page3、景色欣赏 三、网页架构与技术3.1 脑海构思3.2 整体布局3.3 技术说明书 四、网页源码4.1 主页模块源码4.2 源码获取方式 作者寄语 涉及知识 山西旅游主题网页制作&am…

JVM虚拟机(五)强引用、软引用、弱引用、虚引用

目录 一、强引用二、软引用三、弱引用四、虚引用五、总结 引文&#xff1a; 在 Java 中一共存在 4 种引用&#xff1a;强、软、弱、虚。它们主要指的是&#xff0c;在进行垃圾回收的时候&#xff0c;对于不同的引用垃圾回收的情况是不一样的。下面我们就一起来看一下这 4 种引用…