![](https://img-blog.csdnimg.cn/7a9e4cfe05df4598b51ac58e9fa270e2.png?x-oss-process=image/resize,m_fixed,h_224,w_224)
数据结构
文章平均质量分 85
数据结构笔记
bugcoder-9905
长期更新Java学习笔记
展开
-
红黑树remove操作
如果删除的是1个红色节点(父亲和孩子肯定是黑色),不影响该路径上黑色节点的数量,也不会导致删除后的红黑树出现连续两个红色节点的情况,所以不做任何调整工作如果删除的是1个黑色节点,那经过被删除节点的路径就会比其他路径上的黑色节点少一个,需要把被删除节点的孩子补上来,分2种情况:如果补上来的孩子是红色节点,直接把这个孩子涂成黑色, 调整完成如果补上来的孩子是黑色节点,那在当前的路径上没办法再补一个黑色节点出来了,只能从兄弟那里借调黑色节点,再分4种情况我们现在要删除B节点B以及B的孩子NULL是黑色的,删除B后原创 2022-09-13 21:04:16 · 904 阅读 · 1 评论 -
红黑树insert操作
这样就保持了局部和原来一样的红黑树的性质,所以全局也是保持了性质,调整完成!其实这种情况很好解决,把B和C旋转到一条线上,就可以使用情况2的方法解决了。在情况3中,使用交换颜色和右旋转的方法,也会产生连续两个红色节点的问题。原创 2022-09-13 16:26:40 · 294 阅读 · 0 评论 -
红黑树概念和旋转实现
三、红黑树1. 红黑树的概念不是一颗平衡树,节点的左右子树高度大的不超过高度小的两倍。在满足红黑树性质的前提下,旋转的次数要远小于AVL树。C++的map、set的底层数据结构就是红黑树。红黑树特点:树的每一个节点不是黑色就是红色,null是黑色root是黑色从根节点到每一个叶子节点的所有路径上,不能出现连续的红色节点从根节点到每一个叶子节点的所有路径上,黑色节点的数量是相同的思考题:在红黑树中,节点的左右子树的高度差最多不能超过多少?左右子树高度差最多不超过两倍2. 红黑树的原创 2022-09-13 15:08:37 · 744 阅读 · 0 评论 -
并查集实践
我们使用merge的优化,就不使用find的优化了躲避拥堵的最佳路线题目说规划一条路径,使得经过道路的拥挤度的最大值最小。该测试用例输出2,是说我们从1区到3区,可以走1->2->3,此时拥挤度的最大值为2;也可以走1->3,此时拥挤度的最大值为3;故该测试用例输出2我们使用kruskal算法,先从拥挤度小的边开始选取,直到连通s区和t区,这样最后一条选取的边一定是已选道路拥挤度最大的,未选道路拥挤度最小的,这样就能做到在连通的基础上所选取的最大值最小...原创 2022-07-05 18:15:00 · 99 阅读 · 0 评论 -
并查集——最小生成树算法Kruskal
连通图: 在无向图中,若任意两个顶点ViV_iVi和VjV_jVj都有路径相通,则称该无向图为连通图强连通图: 在有向图中,若任意两个顶点ViV_iVi和VjV_jVj都有路径相通,则称该有向图为强连通图连通网: 在连通图中,若图的边具有一定的意义,每一条边都对应着一个数,称为权值,权值代表着连接各个顶点的代价,称这种连通图叫做连通网生成树: 一个连通子图,它包含连通图中全部n个顶点,有n-1条边。如果生成树中再添加一条边,则必定成环最小生成树: 在连通网的所有生成树中,所有边的代价之和最小的生成树原创 2022-07-05 01:08:50 · 1649 阅读 · 0 评论 -
并查集路径压缩算法改进
大多数情况下,查询只关心根节点是谁,并不关心这棵树的形态,查询的时候,我们只要能判断两个节点的根节点是否相同即可但是我们希望查询过程中,效率能稍微高一些。希望树能矮一点,这样我们从某个节点出发找根节点时,会更快速假如当前的并查集如下,我们需要合并7和8所在树的根节点,我们从8出发找到根节点1,我们又从7出发经过相同的路径找到根节点1,然后我们发现根节点相同,不用合并,这样效率就很低了我们进行如下优化:查询的时候将访问过的每个点的父节点修改成树根,这样的方法叫做路径压缩由于无论是查询还是合并,我们都是操作根原创 2022-07-05 23:45:00 · 266 阅读 · 0 评论 -
并查集理论讲解和代码实现
并查集是一种树形的数据结构,主要用于解决一些元素分组的问题。用于处理一些不相交集合的合并以及查询问题并查集的思想是用一个数组表示了整片森林,树的根节点唯一标识了一个集合,我们只要找到了某个元素的树根,就能确定它在哪个集合里我们先讲解一下并查集的构建过程我们假设以上节点两两在一个集合中,左边为父节点,右边为子节点对于前面四组数据,我们构造出如下的结构这出现了问题,根据第4组数据构造集合时,应该把4所在树的根节点与2所在树的根节点相连,正确的集合构造如下:构造并查集过程中,并不是简单的把两个节点相连,而是把原创 2022-07-04 16:25:44 · 416 阅读 · 0 评论 -
C++ STL中的sort源码浅析
文章目录元素少,使用插入排序递归次数过多,使用堆排序主体使用快速排序总结首先提出几个问题:C++ STL默认提供以下两个sort接口void std::sort(const _RanIt _First, const _RanIt _Last)void std::sort(const _RanIt _First, const _RanIt _Last, _Pr _Pred)第一个函数的参数是排序区间,第二个函数的参数是排序区间和指定排序方式的函数对象C++ STL默认使用less函数对象,进行原创 2022-05-16 11:44:34 · 3845 阅读 · 1 评论 -
DFS/BFS搜索迷宫路径
文章目录一、DFS搜索迷宫路径二、BFS搜索迷宫路径一、DFS搜索迷宫路径DFS依赖栈结构先把左上角节点入栈,然后依次查看栈顶元素的右、下、左、上四个方向是否可以走,如果能走就把节点入栈,然后再依次查看依次查看栈顶元素的右、下、左、上四个方向;如果四个方向都不能走,就把栈顶元素出栈最终栈空,则说明退回到了左上角的节点;右下角的节点入栈,则表示找到了出口需要注意的是,每入栈一个节点:需要将当前节点到入栈节点的方向置为NO,保证如果走进死胡同回退后,不会再次往这个错误的方向走需要将刚入栈节原创 2022-05-11 21:23:47 · 1413 阅读 · 0 评论 -
哈夫曼树的概念和代码实现
文章目录一、 基本概念二、构造哈夫曼树三、哈夫曼树的基本性质四、哈夫曼编码五、哈夫曼解码一、 基本概念结点的权: 有某种现实含义的数值结点的带权路径长度: 从结点的根到该结点的路径长度与该结点权值的乘积树的带权路径长度: 树上所有叶结点的带权路径长度之和(wpl=∑i=1nwiliwpl=\sum\limits_{i=1}^{n}w_il_iwpl=i=1∑nwili)哈夫曼树: 在含有nnn个带权叶结点的二叉树中,wplwplwpl 最小 的二叉树称为哈夫曼树,也称最优二叉树(给定叶子结原创 2022-04-18 15:43:26 · 1761 阅读 · 0 评论 -
倒排索引的理论和代码实现
一、倒排索引概念倒排索引常使用在搜索引擎当中,是搜索引擎为文档内容建立索引,实现内容快速检索必不可少的数据结构倒排索引是由单词的集合“词典”和倒排列表的集合“倒排文件”组成的倒排索引的存储:内存索引和B+树索引理解正排索引结构和倒排索引结构;掌握词典、倒排项,倒排列表的具体实现我们在打开搜索网站,我们输入关键字以后,浏览器作为客户端把关键字发到对应的搜索引擎服务器server端,服务器去分析这个关键字,在全网几千万,乃至上亿个所有HTML网页中快速找到我们想要的内容,然后把相关的页面发送给客户原创 2022-04-13 17:46:42 · 3399 阅读 · 0 评论 -
【数据结构】跳跃表SkipList理论和代码实现
一、跳跃表的概念二、跳跃表的find三、跳跃表的insert四、跳跃表的remove五、完整代码原创 2022-04-06 12:07:24 · 1020 阅读 · 0 评论 -
Trie字典树
一、Tire树概念二、add接口三、query接口四、前序遍历接口五、前缀查询接口六、删除字符串的接口原创 2022-04-05 09:56:21 · 492 阅读 · 0 评论 -
深入理解KMP算法
一、暴力搜索算法二、KMP算法思想三、求解next数组四、KMP算法实现五、KMP算法的优化原创 2022-04-04 11:20:48 · 671 阅读 · 0 评论 -
MySQL索引底层实现原理(B树和B+树)
一、B-树索引1. 理论部分2. B树黄色的data表示key索引所在的这一行的数据,data存储的是数据本身内容,还是数据在磁盘上的地址?关于操作系统从磁盘读取索引文件到内存中的几个问题B树的缺点三、B+树B+树特点MySQL最终为什么要采用B+树存储索引结构?原创 2022-03-10 11:08:15 · 5839 阅读 · 1 评论 -
B树、B+树和B*树理论
一、B树基础知识二、B树的插入过程三、B树的删除过程四、B树的磁盘IO优势和搜索效率五、B+树理论部分m阶B+树和m阶B树的区别B+树比B树更适合操作系统的文件索引和数据库索引的原因B树和B+树的区别六、B*树原创 2022-03-08 21:04:41 · 932 阅读 · 0 评论 -
二叉平衡搜索树AVL树
一、AVL树的节点平衡旋转操作1. 右旋2. 左旋3. 左 - 右旋转4. 右 - 左旋转二、AVL树的代码实现1. insert实现2. remove实现原创 2022-02-16 21:40:35 · 203 阅读 · 0 评论 -
BST二叉搜索树常见遍历操作以及面试常见编程题
二叉搜索树原创 2021-12-11 16:29:19 · 672 阅读 · 0 评论 -
深度剖析nginx内存池源码
文章目录一、nginx数据结构二、nginx向OS申请空间ngx_create_pool三、nginx向内存池申请空间四、大块内存的分配与释放五、关于小块内存不释放六、销毁和清空内存池七、编译测试内存池接口功能一、nginx数据结构// SGI STL小块和大块内存的分界点:128B// nginx(给HTTP服务器所有的模块分配内存)小块和大块内存的分界点:4096B#define NGX_MAX_ALLOC_FROM_POOL (ngx_pagesize - 1) // 内存池默认大小#原创 2021-11-15 21:55:49 · 2440 阅读 · 2 评论 -
深度剖析SGI STL二级空间配置器内存池源码
文章目录一、SGI STL二级空间配置器重要成员解读1. 二级空间配置器内存池的结构2. 两个重要的函数(1) _S_round_up(2)_S_freelist_index3. 内存池allocate分配过程一、SGI STL二级空间配置器重要成员解读SGI STL包含了一级空间配置器和二级空间配置器其中一级空间配置器allocator采用malloc和free来管理内存,和C++标准库中提供的allocator是一样的但其二级空间配置器allocator采用了基于freelist自由链表原理的原创 2021-11-11 21:54:46 · 1175 阅读 · 2 评论 -
哈希表&位图&topk&一致性哈希算法
一、线性探测哈希表哈希表的长度最好是素数表中的数,哈希表扩容的时候也是从哈希表中取得,扩容后需要把原来表中的数据重新哈希,存入新的哈希表装载因子:当表的使用量 超过 总容量 * 装载因子 时,需要进行扩容,使用哈希表的 均摊时间复杂度是O(1)enum State { UNUSE, // 从未被使用 USING, // 正在使用 DELETE // 使用后被删除};struct Node { Node(int val = 0, State state = UNUSE)原创 2021-10-29 15:53:15 · 423 阅读 · 0 评论 -
重刷搜索排序算法
一、二分搜索算法1. 非递归代码// 找到返回索引,找不到返回-1int binary_search(const vector<int>& vec, int val) { int left = 0; int right = vec.size() - 1; while (left <= right) { int mid = (left + right) >> 1; if (vec[mid] == val) { return mid; }原创 2021-10-22 22:42:40 · 418 阅读 · 0 评论 -
重刷线性表
文章目录一、仿写vector二、数组中偶数放左边,奇数放右边一、仿写vectorclass Array {public: Array(int size = 10):capacity(size), cur(0) { p_arr = new int[size](); } ~Array() { // 若只是释放,那p_arr还是指向堆内存,成为野指针 // 没必要if(p_arr == nullptr),因为delete nullptr就是空操作,不报错 delete[] p_arr;原创 2021-10-15 15:57:24 · 240 阅读 · 0 评论 -
【复习笔记】B树、B+树
1、二分查找当序列分布较为均匀时效率高int bin_search(vector<int> &nums, int key){ int low = 0; int high = nums.size() - 1; while(low <= high){ int mid = (low + high) / 2; if(nu...原创 2020-02-09 19:27:19 · 422 阅读 · 0 评论 -
【复习笔记】数据结构之图
一、顶点的度对于无向图,顶点的度 = 依附于该顶点的边的数量对于有向图,入度 = 出度 = 边的数量二、顶点—顶点关系的描述三、连通图与强连通图四、子图五、连通分量原创 2020-08-11 12:00:56 · 263 阅读 · 0 评论 -
KMP算法
一、朴素模式匹配算法在主串strstrstr中匹配子串subStrsubStrsubStr,若strstrstr中存在subStrsubStrsubStr,则返回字串在主串中第一次出现的索引。不存在,则返回-1。在 “helloworld” 中匹配 “llo”,匹配成功时的指针状态。朴素模式匹配算法的实现代码:int Index(string str, string subStr){ int cur = 0; int j = 0; int i = cur; wh原创 2020-08-05 11:10:34 · 172 阅读 · 0 评论 -
【复习笔记】二叉排序树、平衡二叉树、哈夫曼树
一、二叉排序树(Binary Search Tree)定义: 二叉排序树又称二叉查找树,对于任何一个结点满足条件:左子树结点值<根节点值<右子树结点值。二叉排序树中序遍历结果是一个升序序列。以下便是一棵二叉排序树:二叉树结点定义struct TreeNode { int val; TreeNode *left; TreeNode *right; TreeNode(int x) : val(x), left(NULL), right(NULL) {}};原创 2020-08-03 17:44:41 · 1707 阅读 · 1 评论 -
C++获取数组最值
数组或vector最大值最小值我们介绍库函数max_element() 及 min_element(),二者返回的都是迭代器或指针。头文件:< algorithm >1.求数组的最大值或最小值1)vector容器 vector<int> nums = {1,2,3,8,0,33,11,9}; int max_num = *max_element(nums.beg...原创 2020-05-02 21:05:26 · 24703 阅读 · 2 评论 -
C++中的sort
原型:void sort(_RandomAccessIterator __first, _RandomAccessIterator __last,_Compare __comp)__first:排序区间的起始地址__last:排序区间的末尾地址__comp:排序方法以上排序区间依然是左闭右开两个参数时,默认升序vector<int> v = {3,1,4,6,0,9...原创 2020-02-23 12:35:38 · 237 阅读 · 0 评论 -
C++中的数组初始化问题
动态数组初始化使用new创建数组的时候,返回的是指向0号元素的指针int nums1 = new int[10]{0,1};* //使用默认值初始化数组** int* nums2 = new int [10] ();** //前两个元素用给的值,其他的元素用int类型默认值int nums3 = new int[10]{};* //使用默认值初始化数组int nums4 = new in...原创 2020-02-18 17:25:07 · 566 阅读 · 0 评论 -
栈和队列遍历二叉树
题目描述算法思想:1、得到根结点后,若左孩子结点不空,不断地将当前结点的左孩子则入栈,第一步完成后,栈顶结点是叶结点2、栈不空时,将栈顶元素弹出并保存到返回的答案数组,并查看当前结点是否有右孩子,有则入栈,然后重复步骤1。没有则接着执行步骤2,直到栈空。 vector<int> ans; //返回的答案数组 vector<Node*> stack; // vect...原创 2020-02-08 16:36:29 · 421 阅读 · 0 评论 -
C++ STL中string的详细总结
一、string的构造函数的形式 //生成空字符串 string(); //生成字符串str的复制品 string(const string& str); string(const char* s); //将字符串str中始于begin、长度为len的部分作为字符串初值,若越界则复制到字符串末尾就截至 string(const string& str, size_t ...原创 2020-02-05 14:46:26 · 757 阅读 · 0 评论 -
二叉树及其线索化
概念1、结点的度:结点拥有的子树个数2、树的度:树内各结点度的最大值3、叶结点(终端结点):度为0的结点4、分支结点:度大于0的结点5、满二叉树:所有的分支结点都存在左右孩子,左右的叶子结点都在同一层的二叉树6、完全二叉树:对一棵具有n个结点的二叉树按层编号,如果编号为i(1<=i<=n)的结点与同样深度的满二叉树中编号为i的结点中位置完全相同,那此树就是一棵满二叉树(结点...原创 2020-02-02 19:07:03 · 1122 阅读 · 0 评论 -
C++队列操作
STL 队列 queue 类成员函数如下:back():返回最后一个元素front():返回第一个元素pop():删除第一个元素,void类型函数,没有返回值,头指针向后移动push():在末尾加入一个元素,尾指针向后移动empty():如果队列为空,则返回1,否则返回0,返回值为boolsize():返回队列中元素的个数,返回值类型为unsigned int由于没有clear()方...原创 2020-02-02 13:49:37 · 455 阅读 · 0 评论 -
排序算法03-插入排序
简单插入排序/** * 时间复杂度为O(n^2) */ #include<iostream>using namespace std;//这里从1号元素开始排序void InsertSort(int* nums, int len){ int temp; for(int i=2; i<len; i++) { if(nums[i...原创 2020-01-31 16:06:40 · 174 阅读 · 1 评论 -
堆排序详解(附可运行代码)
堆排序 /** * parent = (i-1)/2; * son1 = 2*i + 1; * son2 = 2*i + 2; */#include<iostream>#include<vector>using namespace std;void swap(vector<int> &tree, int node1, int ...原创 2020-01-30 12:44:29 · 358 阅读 · 0 评论 -
排序算法01-交换排序
链表冒泡排序用两个指针即可,一个指针指向当前排序结点,另一个指针指向后续相邻结点,比较结点的数据大小并交换。内循环控制每趟排序的终止条件,外循环控制整个排序的终止条件。每一趟排序记录本次是否进行交换,若没有进行交换,则说明所有元素都有序,直接跳出外循环,否则将当前指针cur再次指向首元结点,进行下一次循环。/** * 时间复杂度为O(n^2) * (n-1) + ... + 3 + 2 +...原创 2020-01-29 01:12:38 · 207 阅读 · 0 评论 -
栈的经典用法——判断括号是否匹配
#简单说明栈的特征:本处使用顺序栈判断括号匹配,首先我们知道栈是一种只能在一段操作的线性表。其插入,删除仅能在一端进行操作,就像一个瓶子一样,不管是取东西还是放东西都只能在瓶口进行,那么最后最先进栈的元素就一定是最后出栈的元素。利用这一特性,我们就可以判断括号是否匹配了。#主要思路如下:我们从左到右依次扫描需要判断的字符串,遇见“(”,“{”,“[”就入栈,遇见“)”,“]”,“]”就出栈,...原创 2018-11-04 19:28:57 · 8429 阅读 · 6 评论