数据结构 - 树 堆

news2024/12/24 8:23:27

树、堆是用于频繁插入、排序的数据结构。他是一种排序数据结构而不是排序算法。

堆和树是有区别的

  • 堆:特殊的完全二叉树。“特殊”:数值上特殊,父比子大/小。

1. 为什么用它

书上给的例子有点奇怪:
在这里插入图片描述
他的意思是说:“删除最小+添加一个新数+再找最小”这种操作时间复杂度高,所以需要用堆。我在想:你如果先对列表进行一次排序,然后再进行“删除最小+添加一个新数+再找最小”,不就省事了(取第一个,挨个比较插入,再取第一个)?但是发现这比较评价得比较 N/2 次,但是如果用堆的话就只要比较 logN 就好。也就是说有这个好处

好处:假如你想要招生招到全省前100名,你至少得把所有人的成绩都看一遍,不然万一你漏了一个同学,而那个同学恰好更强怎么办?这个数据结构能够说:假如你想要招生招到全省前100名,我不用看所有人的成绩了,我看几个就可以知道了,不用担心漏掉的人能有更高的分数。

  • 这似乎是一个不完全的排序,其实没有给所有人进行排序,但如果我知道你们学校最高分才200名,那这个学校所有的学生都可以排除。
  • 比如如果我想知道学校谁最富有,我不需要知道每个同学有多少钱,我只要比每个同学的爸爸有钱就好。
  • 有点“本店全市最强、本店全国最强、本店全街最强”的感觉。

2. 如何用?

2.1 建立堆

我本来以为有个什么数的数据结构(类似 queue、stack的),但其实用列表就好(因为完全二叉树是有索引规律的,完全可以依据索引来找到父、子)!当然这个列表是经过排序的,但不是从小到大排序,是建立一个父节点一定比子节点小的完全二叉树,然后把数上的数值按顺序放入列表里面。

2.2 向上、向下移动

我一开始不清楚这个向上、向下移动用在哪个情况下,不都是插入吗?是不是如果数中缺了数,破坏了结构,就向下移动,如果不缺,就向上移动。目前只能这样理解了。

3.3 建立

  1. 先随机拍个序号
  2. 向下移动(因为树的结构未成形)。从n/2 - > 1号节点进行向下移动。最底层节点不形成树,先不遍历。
  3. ?为什么只在一条分支上面往下检查?
    答:因为交换之前,子书是符合规范的,但交换过后,有且仅有一个子树会被破坏,所以不存在既往左边,又向右边。
  4. 这里需要注意,不可先和左边比较,然后和右边比较。这会导致你改了左边又改右边,复杂度增加。
// 堆的建立与排序
#include<vector>
#include<iostream>
using namespace std;
 
int find_min(int a, int b, int c = 99) {
	// 把最小的放第一个 []TODO:有无更好的方法
	if (a > b) {
		a = b;
	}
	if (a > c) {
		a = c;
	}
	return a;
}

void change_pos(vector<int>& num_list, int human_i) {
	// 如果
	int note_index = human_i - 1;
	int child_left = human_i * 2 -1 ;
	int child_right = human_i * 2;

	// 父节点是否比所有子节点都小
	int flag = 0; // 是否影响子节点
 	int exchang_index = note_index;
	int t = 0;
	// 如果没有子节点就退出
	if (human_i > num_list.size() / 2)
		return;

	// 这里需要注意,不可先和左边比较,然后和右边比较。这会导致你改了左边又改右边,复杂度增加
	// 应该三个数取最小:左边先比较,右边后。总共分2类:有右、无右;
	if (child_right <= num_list.size() - 1) {//有右
		t = find_min(num_list[note_index], num_list[child_left], num_list[child_right]);

		if (t == num_list[child_left]) exchang_index = child_left;
		if (t==num_list[child_right]) exchang_index = child_right;
		if (exchang_index != note_index) {
			t = num_list[note_index];
			num_list[note_index] = num_list[exchang_index];
			num_list[exchang_index] = t;
			change_pos(num_list, exchang_index +1);// 转为人的序列
		}
	}
	else {
		// 无右
		t = find_min(num_list[note_index], num_list[child_left]);
		if (t == num_list[child_left]) exchang_index = child_left;
		//if (t == num_list[child_right]) exchang_index = child_right;
		if (exchang_index != note_index) {
			t = num_list[note_index];
			num_list[note_index] = num_list[exchang_index];
			num_list[exchang_index] = t;
			change_pos(num_list, exchang_index + 1);// 转为人的序列
		}
	}
}

int delete_min(vector<int> &num_list, int i) {
	// 弹出第一个 没必要删除头:修改头部,去掉最后一个就好
	int t = 0;
	t = num_list.front();
	num_list[0] = num_list.back(); //? back 返回引用会不会有问题?毕竟最后一个是要被删除的
	num_list.pop_back();
	change_pos(num_list,1);
	return t;
}

int main() {
	vector<int> num_list{ 99,5,36,7,22,17,92,12,2,19,25,28,1,46 }; int t = 0;
	// 从一般开始往前面判断 7-1
	for (int i = 7; i >= 1; i--) {
		change_pos(num_list, i);
	}
	for (int i = 0; i < 14; i++) {
		t = delete_min(num_list, i);
		cout << t << " ";
	}
	return 0;
}

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

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

相关文章

mysql学习笔记1:忘记密码

我使用的mysql版本为&#xff1a;5.6.50&#xff0c;操作系统为&#xff1a;win10 一、修改配置文件my.ini 1、在C:\ProgramData\MySQL\MySQL Server 5.6文件夹下找到my.ini配置文件 2、设置权限认证跳过 找到[mysqld]&#xff0c;在下面这行代码的下面加上 skip-grant-tab…

成兴光 | LED灯珠的封装形式

​成兴光根据不同的应用场合、不同的外形尺寸、散热方案和发光效果。将LED封装形式分为&#xff1a;引脚式、功率型封装、贴片式&#xff08;SMD&#xff09;、板上芯片直装式&#xff08;COB&#xff09;、Chip-LED、UVC金属、陶瓷封装等七个段落讲述。 &#xff08;1&#xf…

供应荧光染料AF532 活性酯,AF532-NHS,CAS:477876-64-5

一&#xff1a;产品描述 1、名称 AF5 532酯 AF532-NHS AF532 活性酯 Alexa Fluor 532 AF532 NHS ester 2、CAS编号&#xff1a;477876-64-5 3、分子式&#xff1a;C34H33N3O11S2 4、分子量&#xff1a;723.77 5、质量控制&#xff1a;95% 6、储存&#xff1a; -20…

分布式账本技术(Distributed Ledger Technology)和区块链(Blockchain)的简要介绍

Distributed Ledger Technology (DLT) 分布式账本技术是应用在资本市场最重要的区块链技术&#xff0c;该技术可以移除当前市场基础设施中的效率极低和成本高昂的部分。 分布式账本&#xff0c;从实质上说就是一个可以在多个站点、不同地理位置或者多个机构组成的网络里进行分…

数据库性能测试-mysql篇

一、数据库主从同步的工作原理 主从复制原理&#xff1a; 上边这张交互图就清楚的标记出了Master节点如何同步到Slave节点 1、首先Master上的修改、删除、新增操作都会被记录到一个叫做binlog的文件中&#xff0c;它是一个二进制日志文件。 2、Slave通过I/O线程读取binlog文件…

AidAim Single File虚拟存档/备份库

AidAim Single File虚拟存档/备份库 Single File System是一个本机Delphi虚拟存档/备份库&#xff0c;提供透明的压缩和强大的加密。单文件系统允许您轻松处理存储在单个文件中的多个文件或文件夹。它还包括高级加密和压缩功能。此解决方案允许您在单个文件中存储小型但功能强大…

单机多GPU训练模型入门指南(torch.nn.DataParallel)

目录 模型部分 1. 指定使用的GPU 2. 使用Torch的数据并行库(将模型搬到GPU上) 3. 保存模型 数据部分 1. 选择GPU 2. 将数据搬到GPU上 3. loss的反向传播修改 查看效果 本文将介绍模型和数据两部分的处理。 模型部分 1. 指定使用的GPU 1.1 导入os库 import os 1.2 …

基于微信小程序的付费自习室系统平台设计与实现的源码+文档

摘要 首先,论文一开始便是清楚的论述了小程序的研究内容。其次,剖析系统需求分析,弄明白“做什么”,分析包括业务分析和业务流程的分析以及用例分析,更进一步明确系统的需求。然后在明白了小程序的需求基础上需要进一步地设计系统,主要包罗软件架构模式、整体功能模块、数据库设…

Oracle Primavera P6V7 SQL异常案例

目录 系统环境 原因分析 解决方案 本案例由一名爱学习的网友提供&#xff0c;经过在Oracle Support的分析整理成文&#xff0c;希望给初学的P6用户提供参考和帮助。 系统环境 简要说明下P6安装的系统环境 操作系统&#xff1a;Windows 7 / Server 2008数据库&#xff1a…

CentOS中使用Docker来部署Postgresql

场景 CentOS7中Docker的安装与配置&#xff1a; CentOS7中Docker的安装与配置_霸道流氓气质的博客-CSDN博客 在上面安装好Docker之后&#xff0c;怎样使用docker部署Postgresql数据库。 注&#xff1a; 博客&#xff1a;https://blog.csdn.net/badao_liumang_qizhi 关注公…

canal-server使用

canal是什么 canal&#xff0c;译意为水道/管道/沟渠&#xff0c;主要用途是基于 MySQL 数据库增量日志解析&#xff0c;提供增量数据订阅和消费。 这句介绍有几个关键字&#xff1a;增量日志&#xff0c;增量数据订阅和消费。这里我们可以简单地把canal理解为一个用来同步增量…

10月11日

gitlab 用https网址拉取项目的时候&#xff0c;出现&#xff1a; error setting certificate verify locations: CAfile: D:/Git/Git/mingw64/ssl/certs/ca-bundle.crt CApath: none原因是&#xff1a; 修改为自己git所在的文件夹即可&#xff08;原因是我是从另外一台电脑直…

AndroidStudio连接真机测试运行

文章目录准备步骤1、打开要连接的手机2、配置AndroidStudio3、用数据线将手机和电脑连起来4、打开 开发者模式后问题1、可能需要下user driver才能连接手机2、电脑连不上手机3、手机连上电脑后不能运行软件运行Android Studio运行虚拟机时会占用较大的电脑内存而自己电脑内存不…

流媒体传输 - HLS 协议

HLS 全称是 HTTP Live Streaming&#xff0c;是一个由 Apple 公司提出的基于 HTTP 的媒体流传输协议&#xff0c;用于实时音视频流的传输。目前 HLS 协议被广泛的应用于视频点播和直播领域。 概述 原理介绍 通过将整条流切割成一个小的可以通过 HTTP 下载的媒体文件&#xff…

SpringBoot中拦截器的使用

SpringBoot中拦截器接口&#xff1a; public interface HandlerInterceptor {default boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {return true;}default void postHandle(HttpServletRequest request, …

【jmeter】windows下使用 (测试MQTT)

1. 添加线程组 二、添加如下请求 1. 添加创建连接请求-选中线程组&#xff0c; 点击右键&#xff0c;添加>取样器>MQTT Connect设置MQTT连接 本次使用本机开启的MQTT服务进行测试&#xff0c;默认ip为127.0.0.1&#xff0c;端口默认1883 2. 添加发布请求-选中线程组 …

面试:各种热修复框架对比

目前Android热修复的技术方案大致可以归类为以下几种&#xff1a; 资源热替换代码热修复动态库替换 资源修复 创建新的AssetManager实例&#xff0c;利用反射加载外部(SD卡)需要热修复的资源路径通过当前Activity实例获取Resouces资源类&#xff0c;然后反射得到mAssets属性&…

powerlevel10k 颜色和图标的自定义设置

文章目录1. 颜色的更改2. 图标的更改3. 附录powerlevel10k 的设置向导命令是p10k configure如果想在这个预定好的设置上面做一些个人的自定义设置&#xff0c;就得更改 powerlevel10k 的配置文件&#xff1a;~/.p10k.zsh 下面的操作主要就是在这个配置文件上面更改。 1. 颜色的…

浅谈芯片验证中的仿真运行之 compilation unit 技术(实践篇)

前言 前面文章,讲述了一些关于SV语法下,编译问题的一些基本概念。其实,芯片验证中仿真工具编译仿真文件、RTL文件的一些规则,依据每一家仿真工具内部的编译原理,都是保密的,用户只要按照仿真工具的使用规则去使用,即可。最近,笔者遇到了一个问题,今天空下来,总结一下…

Windows本地安装Redis且设置服务自启

redis中文网&#xff1a;http://redis.cn/ 如果是安装Windows版的redis需要去GitHub上下载安装包 如果是在Linux上安装&#xff0c;可以直接使用命令进行安装 本次教程是基于Windows系统进行的 GitHub地址&#xff1a;https://github.com/microsoftarchive/redis 选择需要下…