并查集LRU cache

并查集的定义

将n个不同的元素划分成一些不相交的集合。开始时,每个元素自成一个单元素集合,然后按一定的规律将归于同一组元素的集合合并。在此过程中要反复用到查询某一个元素归属于那个集合的运算。适合于描述这类问题的抽象数据类型称为并查集(union find set)

并查集的抽象描述

struct UnionFindSet
属性
数个不相交的集合,通过数组管理 vector
方法
检查两个元素是否属于同一个集合 bool inSameSet(e1,e2);
寻找集合的根元素 e findEigen(e) ;
合并两个元素所在的集合 void merge(e1,e1);
计算当前集合个数 size_t getCnt();

如何表示同一个集合的元素:
可以借助数组抽象结构的方法对同一集合的元素进行分类,为了方便,后续把代表某个集合的元素成为特征元素
首先把每一个元素都被映射成了一个唯一的编号id,id同时也作为数组的下标
规定每一个下标所对应值为集合中其他元素的编号id,如果数组中某一个id位置的值为-x,代表它是一个特征元素,并且集合中有x个元素

![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/acbe9e49efa14b8d80c19692a2c4e07e.png在这里插入图片描述

并查集具体实现

//此处代码忽略了映射关系的构建,数组下标值就是对应的真实元素值
class UnionFindSet
{
private:vector<int> ufs;
public:UnionFindSet(unsigned int n=0):ufs(n,-1){}  //初始状态所有的元素都各自为一个集合,元素之间没有任何关系unsigned int getCnt(){unsigned int cnt=0;for(int x:ufs) if(x==-1) ++cnt;return cnt;}	//统计ufs数组中-1的个数即可获得集合个数unsigned int findEigen(unsigned int e){	unsigned int eigenval=e;while(ufs[eigenval]>=0) eigenval=ufs[eigenval];return eigenval;}	//迭代向上寻找,直至数组中的值为-1bool inSameSet(unsigned int e1,unsigned int e2){return findEigen(e1)==findEigen(e2);}void merge(unsigned int e1,unsigned int e2){unsigned int eigen1=findEigen(e1);unsigned int eigen2=findEigen(e2);if(eigen1!=eigen2) {ufs[eigen1]+=ufs[eigen2];ufs[eigen2]=eigen1;}//把e2所在集合的特征元素对应的值改为e1所在集合的特征元素即可完成2个集合的合并}
};

优化合并与查找

合并优化:小集合合并到大集合中,做到更多的元素能在短时间内找到特征元素
在这里插入图片描述

void merge(unsigned int e1,unsigned int e2)
{unsigned int eigen1=findEigen(e1);unsigned int eigen2=findEigen(e2);if(eigen1!=eigen2){if(ufs[eigen1]>ufs[eigen2]) swap(eigen1,eigen2); //统一规定集合eigen1的元素个数更大ufs[eigen1]+= ufs[eigen2];ufs[eigen2]=eigen1;}
}

查找优化:最理想的情况是每一个节点至多一次找到所在集合的特征元素
在这里插入图片描述
可以考虑每一次进行findEigen查找时对集合元素关系进行调整,使得每一个元素在集合中更接近特征元素
在这里插入图片描述

unsigned int findEigen(unsigned int e) 
{unsigned int eigen = e, prev = -1;while (_ufs[eigen] >= 0) {int tmp = ufs[eigen];//向上查找if (prev>=0) ufs[prev] = tmp;prev = eigen;eigen = tmp;}return eigen;
}

上述代码未经测试,可能存在bug,经测试版代码请参考https://gitee.com/chxchenhaixiao/test_c/blob/master/UnionFindSet/UnionFindSet.h

LRU cache

LRU是Least Recently Used的缩写,意思是最近最少使用,它是一种Cache替换算法
简单地说就是淘汰长久未使用的数据,cache的大小是固定有限的,当空间满时如果还需要加入数据就必须淘汰部分先前的数据

可以把每一个数据块通过一个双向链表级联,人为规定链表尾节点为长时间未使用即将被淘汰的资源,链表头节点为最近使用的数据,借助哈希表实现对各个数据块的快速定位,达到增删查改的时间复杂度均为O(1)
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
代码实现:

class LRUCache {size_t _size=0; //链表当前长度size_t _capacity; //cache最大容量list<pair<int,int>> _list;typedef list<pair<int,int>>::iterator iterator;unordered_map<int,iterator> _map;
public:LRUCache(int capacity) :_capacity(capacity){}int get(int key) {if(!_map.count(key)) return -1;iterator it=_map[key];int val=it->second;_list.push_front(*it);_list.erase(it);_map[key]=_list.begin();return val;}void put(int key, int value) {if(_map.count(key)) //更新节点{iterator it=_map[key];it->second=value;_list.push_front(*it);_list.erase(it);_map[key]=_list.begin();}else{if(_size<_capacity){++_size;_list.push_front({key,value});_map[key]=_list.begin();}else{auto& last=_list.back(); //获取链表尾节点_map.erase(last.first); //删除map中指向尾的映射关系_list.pop_back();   //删除链表尾节点_list.push_front({key,value}); //头插_map[key]=_list.begin(); //更新map}}}
};

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

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

相关文章

Qt (19)【Qt 线程安全 | 互斥锁QMutex QMutexLocker | 条件变量 | 信号量】

阅读导航 引言一、互斥锁1. QMutex&#xff08;1&#xff09;基本概念&#xff08;2&#xff09;使用示例基本需求⭕thread.h⭕thread.cpp⭕widget.h⭕widget.cpp 2. QMutexLocker&#xff08;1&#xff09;基本概念&#xff08;2&#xff09;使用示例 3. QReadWriteLocker、QR…

string类(C++)

哈喽各位&#xff01;&#xff0c;久违了&#xff0c;最近怎么样捏&#xff0c;本次进入C的string类&#xff0c;加油加油呀&#xff01; 随记&#xff1a;鼓励创新&#xff0c;宽容失败&#xff01; 1.标准库的string类 1.1string类的了解 string的文献参考链接-->strin…

Buck变换器闭环控制,simulink仿真模型(适合初学者学习)

Buck变换器&#xff0c;又称为降压斩波器&#xff0c;是一种常见的DC-DC转换器&#xff0c;广泛应用于电源管理领域。它通过开关元件&#xff08;通常是MOSFET或BJT&#xff09;的导通与截止&#xff0c;改变输入电压到负载的平均电压&#xff0c;从而实现电压的降低。在实际应…

828华为云征文——使用Flexus云服务器X实例CentOS镜像下创建MySQL服务器教程

一、概述 1.1 前言 当前正值华为云盛大的828 B2B企业庆典&#xff0c;其中Flexus X实例的特惠活动尤为吸引人眼球。对于追求极致算力表现&#xff0c;并期望在自建MySQL数据库、Redis缓存系统及Nginx服务器部署上获得卓越性能的企业用户而言&#xff0c;这无疑是一个不可多得的…

SpringCloud (1) 服务拆解

1 服务拆解和治理 1.1 服务拆解 微服务的核心就是服务拆分,将传统的大项目拆分为多个微型服务(服务或微服务),实现服务之间"高内聚(微服务职责单一),低耦合(微服务功能相对独立)"的目的 (1) 水平(横向)拆分:先搭出拆分框架,比如【公共服务】(比如:common服务,client…

Python数据分析与可视化(Python绘图详解)

✅作者简介&#xff1a;2022年博客新星 第八。热爱国学的Java后端开发者&#xff0c;修心和技术同步精进。 &#x1f34e;个人主页&#xff1a;Java Fans的博客 &#x1f34a;个人信条&#xff1a;不迁怒&#xff0c;不贰过。小知识&#xff0c;大智慧。 &#x1f49e;当前专栏…

轻量级流密码算法Trivium

轻量级流密码算法Trivium 0x0 Trivium算法简介 Trivium算法是由C&#xff0e;D Canniere和B&#xff0e;Preneel共同设计的一套对称加密算法&#xff0c;Trivium密码算法采用了分组密码和非线性反馈移位寄存器的设计思路。该密码算法总共288比特的内部状态&#xff0c;其中有…

数据篇| 关于Selenium反爬杂谈

友情提示:本章节只做相关技术讨论, 爬虫触犯法律责任与作者无关。 LLM虽然如火如荼进行着, 但是没有数据支撑, 都是纸上谈兵, 人工智能的三辆马车:算法-数据-算力,缺一不可。之前写过关于LLM微调文章《微调入门篇:大模型微调的理论学习》、《微调实操一: 增量预训练(Pretrai…

【手撕算法】快速排序(递归分治法)Python实现

一、算法 class Solution:def Partition(self, nums, low, high):pivotkey nums[low] # 元素copied, nums[low]空了出来while low < high:while low < high and nums[high] > pivotkey:high high - 1 # 直到找到一个nums[high]<pivotkey位置nums[low] nums[h…

Matlab simulink建模与仿真 第十七章(补充离散库和补充数学库)

参考视频&#xff1a;simulink1.1simulink简介_哔哩哔哩_bilibili 一、补充离散库和补充数学库中的模块概览 1、补充离散库 注&#xff1a;每个版本的补充离散库不一定相同&#xff0c;也不是每个版本的库都有如上所有模块。 2、补充数学库 二、离散直接传递函数Ⅱ模块 1、…

学生护眼台灯哪个品牌比较好?五款性价比高的学生护眼台灯

现在的孩子学习压力很大&#xff0c;在学校课程已经塞满了大半天&#xff0c;课后的作业更是不少&#xff0c;空闲时间还需要去课后补习班的数不胜数。用眼的次数非常的高&#xff0c;眼睛很容易感到疲惫&#xff0c;这时候我们一个宝贝大有作用&#xff0c;就是我们的护眼台灯…

软件测试 BUG 篇

目录 一、软件测试的生命周期 二、BUG 1. bug的概念 2. 描述bug的要素 3. bug的级别 4. bug的生命周期 5. 与开发产生争执怎么办&#xff1f;&#xff08;面试高频考题&#xff09; 5.1 先检查自身&#xff0c;是否bug描述不清楚 5.2 站在用户角度考虑并抛出问题 5.3 …

C++/Qt 集成 AutoHotkey

C/Qt 集成 AutoHotkey 前言AutoHotkey 介绍 方案一&#xff1a;子进程启动编写AutoHotkey脚本准备 AutoHotkey 运行环境编写 C/Qt 代码 方案二&#xff1a;显式动态链接方案探索编译动态链接库集成到C工程关于AutoHotkeyDll.dll中的函数原型 总结 前言 上一篇介绍了AutoHotkey…

YOLOv9改进,YOLOv9主干网络替换为RepViT (CVPR 2024,清华提出,独家首发),助力涨点

摘要 轻量级视觉变换器(ViTs)在资源受限的移动设备上表现出优越的性能和较低的延迟,相比之下轻量级卷积神经网络(CNNs)稍显逊色。研究人员发现了许多轻量级 ViTs 和轻量级 CNNs 之间的结构联系。然而,它们在块结构、宏观和微观设计上的显著架构差异尚未得到充分研究。在…

TC-RAG: 图灵完备的检索增强

1. 背景 大型语言模型在众多关键领域均已取得显著进展&#xff0c;并在各种下游任务中展现出卓越性能。 在医疗领域&#xff0c;这些模型尤显潜力&#xff0c;特别是在对责任感和可靠性要求极高的健康护理领域。这些模型通过全面的医学知识预训练&#xff0c;不仅能支持医生做…

堆的向下调整算法和TOPK问题

目录 1.什么是堆&#xff1f; 1.1 向下调整建堆的时间复杂度计算 1.2 堆的结构体设计 2.堆的功能实现&#xff1a; 2.1 堆的插入&#xff1a; 2.2 堆的删除&#xff1a; 2.3 堆排序&#xff1a; 2.4 向下调整建堆&#xff1a; 2.5 TOPK问题&#xff1a; 2.6 向上调整算…

周末愉快!——周复盘

加班的晚上有一个美梦&#xff01; 周末愉快简单复盘结尾 精华&#xff1a; 在这个信息爆炸的时代&#xff0c;我们的大脑每天都被无数的数据和刺激充斥&#xff0c;以至于我们常常感到应接不暇。然而&#xff0c;正如古人所言&#xff1a;“不飞则已&#xff0c;一飞冲天”&am…

音视频入门基础:AAC专题(4)——ADTS格式的AAC裸流实例分析

音视频入门基础&#xff1a;AAC专题系列文章&#xff1a; 音视频入门基础&#xff1a;AAC专题&#xff08;1&#xff09;——AAC官方文档下载 音视频入门基础&#xff1a;AAC专题&#xff08;2&#xff09;——使用FFmpeg命令生成AAC裸流文件 音视频入门基础&#xff1a;AAC…

Paragon NTFS for Mac和Tuxera NTFS for Mac,那么两种工具有什么区别呢?

我们在使用Mac系统读取U盘的过程中往往会遇到一个问题&#xff0c;那就是U盘插进电脑无法显示&#xff0c;或者只能读取不能编辑。出现这种情况的原因就一般是格式错误。 很多小伙伴在解决这种问题的时候会选择使用U盘读写工具&#xff0c;那么哪一种读写工具比较好呢&#xf…

毕业设计选题:基于springboot+vue+uniapp的驾校报名小程序

开发语言&#xff1a;Java框架&#xff1a;springbootuniappJDK版本&#xff1a;JDK1.8服务器&#xff1a;tomcat7数据库&#xff1a;mysql 5.7&#xff08;一定要5.7版本&#xff09;数据库工具&#xff1a;Navicat11开发软件&#xff1a;eclipse/myeclipse/ideaMaven包&#…