list的模拟实现
目录
一、构造和扩容机制
二、普通迭代器
三、const迭代器
四、tip
有了前面vetcor的基础呢,我们在学习和使用list上就更加的方便快捷,浅显易懂了,所以相似的部分我就不做过多的言语阐述了,在使用方面呢,大家可以学习我之前看的c++网站,和vector和string的使用都是差不多的,重点要放在list的迭代器部分
一、构造和扩容机制
template <class T>class list{typedef list_node<T> Node;public:void empty_init(){_head = new Node;_head->_next = _head;_head->_prev = _head;}list(){empty_init();}void push_back(const T&val){Node* tail = _head->_prev;Node* newnode = new Node(val);tail->_next = newnode;newnode->_prev = tail;newnode->_next = _head;_head->_prev = newnode;}private:Node* _head;
空初始化的时候我们也需要构造,所以缺省值我们给一个匿名对象进行初始化,这个我们在vector的模拟实现里面有重点说到
template <class T>
struct list_node
{T _data;list_node<T>* _next;list_node<T>* _prev;list_node(const T& data=T()):_data(data),_next(nullptr),_prev(nullptr){}
};
二、普通迭代器
void listtest1()
{list<int> l;l.push_back(1);l.push_back(2);l.push_back(3);l.push_back(4);list<int>::iterator it = l.begin();while (it != l.end()){cout << *it << " ";++it;}
}
这里我们还没有实现迭代器
这是一个带头双向循环链表,我们结合迭代器来看,由于它是一个结构体,我们解引用并不能得到它的数据,++it也不能得到向后走,!=也判断不了end(),因为里面存在着数据和前后指针,这时候我们就要运算符重载和封装这里
这里我们为什么不用class来写那个list_node 呢因为你写class就要把它定义成友元,而这里我们是要把这个类的权限全部开放所以我们定义成struct
template <class T>
struct list_iterator
{typedef list_node<T> Node;typedef list_iterator<T> self;Node* _node;list_iterator(Node* node):_node(node){ }self& operator++(){_node = _node->_next;return *this;}T& operator*(){return _node->_data;}bool operator!=(const self&s){return _node != s._node;}};
我们来阐述一下这里的行为,我们封装了一个Node,实例化了一个对象,写出构造函数,++让里面的指针++返回这个Node的下一个位置的引用,下面也是类似,就是指针完成不了的事情我们通过间接的方式来让类完成
typedef list_iterator<T> iterator;
iterator begin()
{return _head->_next;
}
iterator end()
{return _head;
}
这里begin和end返回指着可以的原因是单参数的构造支持隐式类型的转换
这里重要的就是封装,封装屏蔽了底层差异和实现细节,提供统一访问修改遍历方式
这算是一种模拟指针的行为
我们简化了这里的接口,list_iterator封装了链表节点的指针,通过重载一系列运算符,用户可以像指针一样遍历链表,而不必关心节点如何连接
这里我们先封装一个简单的
先把其他的架子实现出来
首先是删除
iterator erase(iterator pos)
{Node* cur = pos._node;Node* prev = cur->_prev;Node* next = cur->_next;delete cur;prev->_next = next;next->_prev = prev;return iterator(next);
}
删除这里会涉及迭代器失效的问题,有关于迭代器失效可以看一下我vector里面有详细的写,总而言之就是这里pos的位置删除了,而你的迭代器没有进行及时的更新,所以我们这里让迭代器指向下一个位置
iterator insert(iterator pos, const T& val)
{Node* cur = pos._node;Node* newnode = new Node(val);Node* prev = cur->_prev;prev->_next = newnode;newnode->_prev = prev;newnode->_next = cur;cur->_prev = newnode;return iterator(newnode);
}
一般来说这里的insert不会发生迭代器失效,但是库里面有写,而且可以和上面统一一下
这样子我们的头插头删尾插尾删就可以复用这里的
void push_back(const T&val)
{insert(end(), val);}
void push_front(const T& val)
{insert(begin(), val);
}
void pop_back(const T& val)
{erase(end(), val);
}
void pop_front(const T& val)
{erase(begin(), val);
}
void clear()
{iterator it = begin();while (it != end()){it = erase(it);}
}
这个时候我们上面的删除迭代器就派上用场了,删除完我们返回下一个迭代器位置就行了
我们的析构就可以套用这个clear了
~list(){clear();delete _head;_head = nullptr;}
接下来我们来实现一下拷贝构造
list(list<T>& l)
{empty_init();for (auto e : l){push_back(e);}
}
这里不用const原因是因为e不是const对象,等下我们实现了const迭代器就可以实现了
再让我们实现一下赋值
首先是传统写法
//lt3=lt1//list<T>& operator=(list<T>& l)//{// if (this != &l)// {// clear();// for (auto e : lt)// {// push_back(e);// }// }//}
现代写法
void swap(list<T>& l)
{std::swap(_head, l._head);
}
list<T>& operator=(list<T>& l)
{swap(l);return *this;
}
交换头节点的指针就可以了
为了不让有的人去获取这个链表的size时时间复杂度是o(n),我们添加一个szie在private那里,在初始化那里给上0,insert那里++,erase那里--就好了
void swap(list<T>& l)
{std::swap(_head, l._head);std::swap(_size, l._size);
}
我们再来看一下后置++
self operator++(int)
{self tmp(*this);_node = _node->_next;return tmp;
}
self operator--(int)
{self tmp(*this);_node = _node->_prev;return tmp;
}
bool operator==(const self& s)
{return _node == s._node;
}
迭代器是不需要实现析构函数的,因为它不需要把那个节点给带走,你可以访问节点,但是不能带走不属于它的节点
为了支持自定义类型的实例化访问我们还需要实现->
T* operator->()
{return &_node->_data;
}
三、const迭代器
template <class T>
struct list_const_iterator
{typedef list_node<T> Node;typedef list_const_iterator<T> self;Node* _node;list_const_iterator(Node* node):_node(node){}self& operator++(){_node = _node->_next;return *this;}self operator++(int){self tmp(*this);_node = _node->_next;return tmp;}self& operator--(){_node = _node->_prev;return *this;}self operator--(int){self tmp(*this);_node = _node->_prev;return tmp;}const T& operator*(){return _node->_data;}const T* operator->(){return &_node->_data;}bool operator!=(const self& s){return _node != s._node;}bool operator==(const self& s){return _node == s._node;}};
typedef list_const_iterator<T> const_iterator;
const_iterator begin() const
{return _head->_next;
}
const_iterator end() const
{return _head;
}
void print_list(const list<int>& l)
{list<int>::const_iterator it = l.begin();while (it != l.end()){cout << *it << " ";++it;}
}
这个const_iterator不是const iterator的类型,指针本身可以被修改,但是指针指向的内容不能被修改
那我们这里写成两个能不能复用一下搞成一个呢,我们看一下库里面的
同一个类模板,实例化参数不同,就是完全不同的类型
template <class T, class Ref,class Ptr >struct list_iterator{typedef list_node<T> Node;typedef list_iterator<T, Ref, Ptr> self;Node* _node;list_iterator(Node* node):_node(node){}self& operator++(){_node = _node->_next;return *this;}self operator++(int){self tmp(*this);_node = _node->_next;return tmp;}self& operator--(){_node = _node->_prev;return *this;}self operator--(int){self tmp(*this);_node = _node->_prev;return tmp;}Ref & operator*(){return _node->_data;}Ptr* operator->(){return &_node->_data;}bool operator!=(const self& s){return _node != s._node;}bool operator==(const self& s){return _node == s._node;}};
typedef list_iterator<T,T&,T*> iterator;
typedef list_iterator<T,const T&,const T*> const_iterator;
我们定义了两个类,我们也不知道这是什么类,留给后面来定义,只知道Ref相当于&类型的,Ptr代表*类型的,
Ref & operator*()
{return _node->_data;
}
Ptr* operator->()
{return &_node->_data;
}
比如说当我们实例化int的时候,普通对象先传给T&,再把T&传给Ref,Ref就可以实例化出来这个类进行使用,定义了一个const对象就实例化出来一个const的类出来,看似是一个类,在当你实例化普通和const对象的时候其实是两个类
四、tip
template<class T>
void print_list(const list<T>& l)
{list<T>::const_iterator it = l.begin();while (it != l.end()){cout << *it << " ";++it;}for (auto e : l){cout << e << " ";}cout << endl;
}
void listtest3()
{list<int> l;l.push_back(1);l.push_back(2);l.push_back(3);l.push_back(4);print_list(l);
}
这段代码我们会发现编译不通过
template<typename T>
void print_list(const list<T>& l)
{typename list<T>::const_iterator it = l.begin();while (it != l.end()){cout << *it << " ";++it;}for (auto e : l){cout << e << " ";}cout << endl;
}
改成这样就可以了,因为你list里面是模板,模板又没有实例化,编译器不敢去类里面找,去里面找也没有实例化,其次是你const_iterator是静态成员变量还是内嵌类型不知道,编译器分不清,前面加一个typename就是告诉编译器这里是一个类型,等list<t>实例化,再去实例化类型里面去找
那我们这个print如果想针对所有容器怎么办
template<typename Container>void print_container(const Container& l){typename Container::const_iterator it = l.begin();while (it != l.end()){cout << *it << " ";++it;}for (auto e : l){cout << e << " ";}cout << endl;}void listtest3(){vector<string> v;v.push_back("11111111111");v.push_back("11111111111");v.push_back("11111111111");v.push_back("11111111111");print_container(v);}}
和上面是一样的玩法,把实例化这个类型传给了container
模板实现了泛型编程,把我们本来干的活交给了编译器
好了list就到这里结束了,接下来是栈和队列,写的不好的地方欢迎大家指出
相关文章:
list的模拟实现
目录 一、构造和扩容机制 二、普通迭代器 三、const迭代器 四、tip 有了前面vetcor的基础呢,我们在学习和使用list上就更加的方便快捷,浅显易懂了,所以相似的部分我就不做过多的言语阐述了,在使用方面呢,大家可以学…...
pandas DataFrame 数据筛选与排序
数据筛选: df[df[列标签] > xxx] 使用 &(与) |(或) 拼接多个条件代码应用: &(与)应用 # 引用 pandas import pandas as pd # 定义数据 data {"产品":["男装","女装","男鞋","女鞋"…...
elpis全栈课程学习之elpis-core学习总结
elpis全栈课程学习之elpis-core学习总结 核心原理 elpis-core是全栈框架elpis的服务端内核,主要应用于服务端接口的开发以及页面的SSR渲染,elpis-core基于约定优于配置的原理,通过一系列的loader来加载对应的文件,大大节约用户的…...
零基础deep seek+剪映,如何制作高品质的视频短片
以下是专为零基础学习者设计的 剪映专业版详细教程+Deep seek配合制 ,包含从入门到精通的系统化教学,配合具体操作步骤与实用技巧: 基于DeepSeek与剪映协同制作高品质视频短片的专业流程指南(2025年最新实践版&#x…...
解决单元测试 mock final类报错
文章目录 前言解决单元测试 mock final类报错1. 报错原因2. 解决方案3. 示例demo4. 扩展 前言 如果您觉得有用的话,记得给博主点个赞,评论,收藏一键三连啊,写作不易啊^ _ ^。 而且听说点赞的人每天的运气都不会太差࿰…...
Git基本命令索引
GIT基本命令索引 创建代码库修改和提交代码日志管理远程操作操作分支 创建代码库 操作指令初始化仓库git init克隆远程仓库git clone 修改和提交代码 操作指令查看文件状态git status文件暂存git add文件比较git diff文件提交git commit回滚版本git reset重命名或者移动工作…...
非平稳时间序列分析(二)——ARIMA(p, d, q)模型
此前篇章(平稳序列): 时间序列分析(一)——基础概念篇 时间序列分析(二)——平稳性检验 时间序列分析(三)——白噪声检验 时间序列分析(四)—…...
[代码规范]接口设计规范
一个优雅的接口要如何设计?有哪些设计规范可以遵循? 下面抛砖引玉,分享一些规范。 目录 1、RESTful API 设计最佳实践 2、Shneiderman 的 8 条黄金法则 3、Nielsen 的 10 条启发式规则 1、RESTful API 设计最佳实践 一共18条,参考…...
4-3自定义加载器,并添加功能
一、自定义类加载器的实现步骤 继承ClassLoader类 自定义类加载器需继承java.lang.ClassLoader,并选择性地重写以下方法: findClass(String name):核心方法,用于根据类名查找并加载类的字节码。需从自定义路径(…...
北京大学DeepSeek提示词工程与落地场景(PDF无套路免费下载)
近年来,大模型技术飞速发展,但许多用户发现:即使使用同一款 AI 工具,效果也可能天差地别——有人能用 AI 快速生成精准方案,有人却只能得到笼统回答。这背后的关键差异,在于提示词工程的应用能力。 北京大…...
SSH密码更改
Windows User目录下的.ssh/config,全部删除 linux 在主用户文件夹,ctrlh显示隐藏文件。删除.shh文件夹内所有文件。...
蓝桥备赛(四)- 数组(下)
一 、 字符数组 1.1 介绍 数组的元素如果是字符类型 , 这种数组就是字符数组 , 字符数组可以是一维数组 , 可以是二维数组 (多维数组)。 接下来主要讨论一维的字符数组 : char arr1[5] //一维数组 char arr2[3][5] // 二维数组 C语言 中…...
基金 word-->pdf图片模糊的解决方法
1. 首先需要Adobe或福昕等pdf阅读器。 2. word中 [文件]--[打印],其中打印机选择pdf阅读器,例如此处我选择福昕阅读器。 3. 选择 [打印机属性]--[编辑]--[图像],将所有的采样、压缩均设置为 关闭。点击[另存为],保存为 基金报告…...
身为小兵,如何提升不可替代性?
之前聊过,研发、PIE、PE、可靠性等岗位,主要是对物的工作, 这类岗位,如何提升不可替代性? 我的经验是,学会识别创造性工作or重复性工作。 尽可能地做创造性工作,推重复性工作。 销售、采购、HR等岗位,主要是对人的工作, 这类岗位,如何提升不可替代性? 我的思考…...
easyExcel使用案例有代码
easyExcel 入门,完成web的excel文件创建和导出 easyExcel官网 EasyExcel 的主要特点如下: 1、高性能:EasyExcel 采用了异步导入导出的方式,并且底层使用 NIO 技术实现,使得其在导入导出大数据量时的性能非常高效。 2、易于使…...
linux服务器更新jar包脚本
【需求】Java每次发布新的版本都需要先kill掉原来的服务,然后再启动新的包 有了这个脚本只需要把包替换掉,服务会自动kill 以8184 为例 完整的脚本如下 #!/bin/bash# 检查端口 8184 是否被占用 PORT8184 PID$(lsof -t -i:$PORT)if [ -n "$PID…...
Tomcat 乱码问题彻底解决
1. 终端乱码问题 找到 tomcat 安装目录下的 conf —> logging.properties .修改ConsoleHandler.endcoding GBK (如果在idea中设置了UTF-8字符集,这里就不需要修改) 2. CMD命令窗口设置编码 参考:WIN10的cmd查看编码方式&…...
dify绑定飞书多维表格
dify 绑定飞书和绑定 notion 有差不多的过程,都需要套一层应用的壳子,而没有直接可以访问飞书文档的 API。本文记录如何在dify工具中使用新增多条记录工具。 创建飞书应用 在飞书开放平台创建一个应用,个人用户创建企业自建应用。 自定义应…...
深入浅出:插入排序算法完全解析
1. 什么是插入排序? 插入排序(Insertion Sort)是一种简单的排序算法,其基本思想与我们整理扑克牌的方式非常相似。我们将扑克牌从第二张开始依次与前面已排序的牌进行比较,将其插入到合适的位置,直到所有牌…...
MySQL--DQL、DML、DDL、DCL概念与区别
在SQL中,根据功能和操作对象的不同,通常将语文分为四大类:DQL(数据查询语言)、DML(数据操作语言)、DDL(数据定义语言)、DCL(数据控制语言) 一、D…...
【设计原则】里氏替换原则(LSP):构建稳健继承体系的黄金法则
深入理解里氏替换原则(LSP)及其在C#中的实践 一、什么是里氏替换原则?二、为什么需要LSP?三、经典违反案例:矩形与正方形问题四、正确的设计实践方案1:通过接口分离方案2:使用抽象类 五、LSP的关…...
SQL的select语句完整的执行顺序
SQL的SELECT语句的执行顺序可以用"做菜流程"来类比理解。虽然我们写SQL时按SELECT…FROM…WHERE…顺序写,但数据库执行顺序完全不同。以下是通俗易懂的讲解(附流程图和示例): 🔧 执行顺序流程图:…...
【Vue3】浅谈setup语法糖
Vue3 的 setup 语法糖是通过 <script setup> 标签启用的特性,它是对 Composition API 的进一步封装,旨在简化组件的声明式写法,同时保留 Composition API 的逻辑组织能力。以下是其核心概念和原理分析: 一、<script setu…...
算法-二叉树篇27-把二叉搜索树转换为累加树
把二叉搜索树转换为累加树 力扣题目链接 题目描述 给出二叉 搜索 树的根节点,该树的节点值各不相同,请你将其转换为累加树(Greater Sum Tree),使每个节点 node 的新值等于原树中大于或等于 node.val 的值之和。 提…...
FPGA开发,使用Deepseek V3还是R1(3):系统级与RTL级
以下都是Deepseek生成的答案 FPGA开发,使用Deepseek V3还是R1(1):应用场景 FPGA开发,使用Deepseek V3还是R1(2):V3和R1的区别 FPGA开发,使用Deepseek V3还是R1&#x…...
《国密算法开发实战:从合规落地到性能优化》
前言 随着信息技术的飞速发展,信息安全已成为全球关注的焦点。在数字化时代,数据的保密性、完整性和可用性直接关系到国家、企业和个人的利益。为了保障信息安全,密码技术作为核心支撑,发挥着至关重要的作用。国密算法,即国家密码算法,是我国自主设计和推广的一系列密码…...
DeepSeek开源周Day5压轴登场:3FS与Smallpond,能否终结AI数据瓶颈之争?
2025年2月28日,DeepSeek开源周迎来了第五天,也是本次活动的收官之日。自2月24日启动以来,DeepSeek团队以每天一个开源项目的节奏,陆续向全球开发者展示了他们在人工智能基础设施领域的最新成果。今天,他们发布了Fire-F…...
Linux:进程替换
目录 进程程序替换 替换原理 进程替换相关函数 环境变量与进程替换函数 命令行解释器(my_xshell) 进程程序替换 上一篇进程控制讲到,父进程创建子进程就是为了让子进程去做一些另外的事情,但是不管怎么说,子进程的部分代码也还是父进程…...
CSS 日常开发常用属性总结
文章目录 CSS 日常开发常用属性总结一、 常用 CSS 属性1、布局相关(1)display:(2)position:(3)float:(4)clear: 2、尺寸与溢出&#x…...
Python 绘制迷宫游戏,自带最优解路线
1、需要安装pygame 2、上下左右移动,空格实现物体所在位置到终点的路线,会有虚线绘制。 import pygame import random import math# 迷宫单元格类 class Cell:def __init__(self, x, y):self.x xself.y yself.walls {top: True, right: True, botto…...
了解Java集合的概念和体系:Collection<T>、Collections与Stream的使用
学习目标 本文知识是对集合层级的介绍,应用开发中实际使用的是他们的子级,感兴趣的小伙伴或者想深入了解有关Java集合知识的朋友可以选择阅读! Stream的方法使用使用部分代码块内大多有两种实现方式,是为了更好的理解方法底层的代…...
扫描局域网可用端口
site: https://mengplus.top #SiliconFlow : 在Linux系统,你可以使用一个简单的Bash脚本来扫描局域网中可用的端口。这个脚本可以使用nmap工具来实现。nmap是一个强大的网络扫描工具,可以用来探测网络中的主机和端口。 以下是一个简单的Bash脚本&#…...
算法分析 —— 《栈》
文章目录 删除字符串中的所有相邻重复项题目描述:代码实现:代码解析: 比较含退格的字符串题目描述:代码实现:代码解析: [基本计算器 II](https://leetcode.cn/problems/remove-all-adjacent-duplicates-in-…...
693. 交替位二进制数
交替位二进制数 题目描述尝试做法推荐做法 题目描述 给定一个正整数,检查它的二进制表示是否总是 0、1 交替出现:换句话说,就是二进制表示中相邻两位的数字永不相同。 示例 1: 输入:n 5 输出:true 解释…...
uniapp中使用leaferui使用Canvas绘制复杂异形表格的实现方法
需求: 如下图,要实现左图的样式,先实现框架,文字到时候 往里填就行了,原来的解决方案是想用css,html来实现,发现实现起来蛮麻烦的。我也没找到合适的实现方法,最后换使用canvas来实现ÿ…...
Java 反射(Reflection)的原理和应用
反射(Reflection)是 Java 语言的一项强大功能,它允许程序在运行时动态地获取类的信息,并且可以操作这些信息,如创建对象、调用方法、访问字段等。反射机制的核心在于 Java 的 类加载机制 和 动态类型检查,使…...
Linux top 常用参数记录
top命令经常用来监控linux的系统状况,能实时显示系统中各个进程、线程的资源占用情况,是常用的性能分析工具。 一些常用参数记录 top的使用方式 top [-d number] | top [-bnp] # 5s 更新一次 top -d 5# 进行2次top命令的输出结果 top -n 2# 查看进程的…...
hive之LEAD 函数详解
1. 函数概述 LEAD 是 Hive 中的窗口函数,用于获取当前行之后指定偏移量处的行的值。常用于分析时间序列数据、计算相邻记录的差异或预测趋势。 2. 语法 LEAD(column, offset, default) OVER ([PARTITION BY partition_column] [ORDER BY order_column [ASC|DESC]…...
Element Plus中el-tree点击的节点字体变色加粗
el-tree标签设置 <el-tree class"tree":data"treeData":default-expand-all"true":highlight-current"true"node-click"onTreeNodeClick"><!-- 自定义节点内容,点击的节点字体变色加粗 --><!-- 动…...
.gitignore 设置后不见效的解决方法中,方案一就可以了
遇到的问题:你的 .gitignore 文件中包含了 unpackage/ 目录,但它不起作用的原因可能有以下几个: 1. 文件或目录已经被 Git 跟踪 .gitignore 只能忽略 未被 Git 追踪 的文件或目录。如果 unpackage/ 目录已经被提交到 Git 版本库中ÿ…...
git提交管理
git提交管理 scoop install nodejs # windows npm install --save-dev commitlint/config-conventional commitlint/cli # non-windows npm install --save-dev commitlint/{cli,config-conventional} # windows将commitlint.config.js修改为utf8编码, 默认utf16编码 echo &qu…...
DeepSeek八大组合软件,效率加倍
DeepSeek王炸组合:开启2025年高效工作与创意新时代 在科技飞速发展的2025年,人工智能和各类工具的融合正不断重塑我们的工作与生活方式。DeepSeek作为一款强大的工具,与众多应用组成的王炸组合,展现出了令人瞩目的能力。今天&…...
TCP和UDP比较
以下是 TCP(传输控制协议) 和 UDP(用户数据报协议) 的详细对比,涵盖核心特性、应用场景及技术差异: 1. 核心特性对比 特性TCPUDP连接方式面向连接(需三次握手建立连接)无连接&#…...
【实战篇】【深度解析DeepSeek:从机器学习到深度学习的全场景落地指南】
一、机器学习模型:DeepSeek的降维打击 1.1 监督学习与无监督学习的"左右互搏" 监督学习就像学霸刷题——给标注数据(参考答案)训练模型。DeepSeek在信贷风控场景中,用逻辑回归模型分析百万级用户数据,通过特征工程挖掘出"凌晨3点频繁申请贷款"这类魔…...
Postgresql高可用之Pacemaker+Corosync
简介 Pacemaker 是 ClusterLabs 开源高可用性集群堆栈的资源管理器。它协调配置、启动、监控和跨所有集群节点恢复相互关联的服务。在这套高可用架构用会用到Pacemaker、Corosync以下是对其功能作用的说明。 Corosync :主要负责 集群通信和成员管理,它用…...
智能成绩表
智能成绩表 真题目录: 点击去查看 E 卷 100分题型 题目描述 小明来到学校当老师,需要将学生按考试总分或单科分数进行排名,你能帮帮他吗? 输入描述 第 1 行输入两个整数,学生人数 n 和科目数量 m。 0 < n < 1000 < m < 10第 2 行输入 m 个科目名称,彼此之…...
制作安装win10系统U盘详细步骤
https://www.microsoft.com/zh-cn/software-download/windows10 ①微软官方链接,下载工具 ②下载之后,点击鼠标右键用管理员身份运行 ③等待几分钟 ④出现许可条款点击接受 ⑤点击为另一台电脑安装介质,然后下一步 ⑥根据需要选择版本。 体系…...
【RAG】Embeding 和 Rerank学习笔记
Q: 现在主流Embeding模型架构 在RAG(Retrieval-Augmented Generation)系统中,嵌入模型(Embedding Model) 是检索阶段的核心组件,负责将查询(Query)和文档(Document&#…...
华为 Open Gauss 数据库在 Spring Boot 中使用 Flyway
db-migration:Flyway、Liquibase 扩展支持达梦(DM)、南大通用(GBase 8s)、OpenGauss 等国产数据库。部分数据库直接支持 Flowable 工作流。 开源代码仓库 Github:https://github.com/mengweijin/db-migrat…...
B/B+树与mysql索引
数据结构操作网站:https://www.cs.usfca.edu/~galles/visualization/Algorithms.html B树 算法平均最差空间O(n)O(n)搜索O(log n)O(log n)插入O(log n)O(log n)删除O(log n)O(log n) B树 算法平均最差空间O(n)O(n)搜索O(log n)O(log n)插入O(log n)O(log n)删除O(…...