数据结构高阶
文章平均质量分 55
不会学习的小白O^O
这个作者很懒,什么都没留下…
展开
-
LCA算法(求两节点最近公共祖先)
和前面暴搜中第二种同步前进法一样的,先让深度大的节点y向上走到与x同深度 , 然后x和y一起向上走,和爆搜不一样的是,向上走的按照倍增思想走的,不是一步一步地向上走,因此速度更快。总结:按照增量递减的方式,到达的节点深度比x的深度小时,什么也不做,到达的深度大于等于x深度时,y上移,直到增量为0,此时x,y在同一深度。2.减少增量,x,y同时向上走2^2步,此时到达的节点不同,x,y上移 x=F[x][2] , y=F[y][2]4.减少增量,x,y同时向上走2^0步,此时到达的节点相同,什么也不做。原创 2023-12-01 23:27:53 · 388 阅读 · 0 评论 -
Bellman-ford 贝尔曼-福特算法
它也有明显的缺点,它的时间复杂度O(N*E)(N是点数 , E是边数)普遍是要高于Dijkstra算法O(N^2)的,像这里,我们使用邻接矩阵实现,那么遍历所有边的数量的时间复杂度就是O(N^3),这里也可以看出Bellman-ford就是一种暴力求解更新。我们这边i-->j的边只更新一次。而且可以判断是否负权回路。原创 2023-10-31 23:00:55 · 347 阅读 · 0 评论 -
单源最短路径 -- Dijkstra
针对一个带权有向图G , 将所有节点分为两组S和Q , S是已经确定的最短路径的节点集合,在初始时为空(初始时就可以将源节点s放入,毕竟源节点到自己的代价是0 ), Q为其余未确定最短路径的节点集合,松弛即对每一个相邻节点v,判断源节点s到节点u的代价与u到v的代价之和是否比原来的s到v的代价更小,若代价比原来小则要将s到v代价更新为s到u与u到v的代价之后,否则维持原样,如此反复,直到Q集合。Dijkstra算法就适用于解决带权重的有向图上的单源最短路径问题 --带有负权路的,搞不定。原创 2023-10-26 02:14:53 · 247 阅读 · 0 评论 -
图的基本概念
在无向图中,(u , v)是E(G)的一条边,则称u和v互为邻接顶点,并称边(u,v)依附于顶点u和v , 在有向图中,若(u , v)是E(G)的一条边,则称顶点u邻接到v,顶点v邻接自顶点u,并称<u,v>与顶点u和顶点v相关联。在图G = (V ,E)中,若从顶点Vi出发有一组边使其可达到顶点Vj,则称顶点Vi到顶点Vj的顶点序列为从顶点Vi到顶点Vj的路径。:在有n个顶点的无向图中,若有n*(n-1) /2 条边,即任意两个顶点之间有且仅有一条边,则称此图为。树关注的节点(顶点)中存的值。原创 2023-10-16 22:37:41 · 77 阅读 · 0 评论 -
并查集路径压缩
我们来看看如果要是100个数,往20个数的集合合并如何。那么我们应该,把数据量小的集合往数据量大的合并。原创 2023-10-15 12:31:40 · 92 阅读 · 0 评论 -
并查集的实现的应用
就假如 s1={0,6,7,8} , s2={1,4,9} , s3={2,3,5} ,这三个小分队内的成员互相认识,这样就形成了3个集合,并把编号为 0 1 2的三名学生分别作为小分队的队长。现招了10名学生,来自不同的学校,刚开始互相不认识,给10名学生编号 :{0,1,2,3,4,5,6,7,8,9};10名学生去旅游,在旅游的路上,有的学生互相认识,之后组成了群体,结伴旅行,这时候我们就形成了一个一个的集合。我们如何通过10名同学的名字,进行编号?原创 2023-10-10 23:27:51 · 35 阅读 · 0 评论 -
哈希应用 : 位图和布隆过滤器
近似算法: 把一个文件放进布隆过滤器当中,在把另一个文件与布隆过滤器进行比对,在就是交集,当然这里存在两个问题就是,在也有可能存在误判,然后没有去重。我们的位图只能处理整数,但是要是我们来了字符串,但是数据量又很大很大我们就得用布隆过滤器。在这里我们可以用一种哈希的新方法 -- 又快又节省内存(位图)BloomFilter能否支持删除呢?原创 2023-10-09 13:37:15 · 75 阅读 · 0 评论 -
哈希 -- 开散列(哈希桶)
这里我们要是用string(string来做key)来取模,再增加一个模板参数,配一个取模的仿函数即可。原创 2023-09-24 01:43:04 · 91 阅读 · 0 评论 -
哈希 -- 开散列
但是当负载因子到一个基准值,就扩容,基准值越大冲突越大,冲突越多,效率越低,但是空间利用率越高。因为string也是常常作为key,那么我们怎么才能不显示的传关于string的仿函数。基准值越小,冲突越少,效率越高,空间利用率越低。------------------使用特化。我们再用上面代码来实现我们的统计次数问题。以上就是我们的线性探测基本代码实现。一般基准值设为0.7。原创 2023-09-22 13:57:47 · 51 阅读 · 0 评论 -
set和map通过一颗红黑树进行封装
原因是因为 , 我们的RBTree当中不仅仅有insert插入 (虽然insert插入 ,set比较的key , map比较的pair当中的first 也就是key ) ,还有find ,那么我们find比较的也是key了,我们多传一个模板参数K ,可以利用模板K ,来进行key的比较,(虽然set对find没有影响,但是map当中find还是有影响的,不然需要取pair当中的first来进行比较,不太便利)data对于map而言是pair , 我们得用pair的first来比。原创 2023-09-19 16:49:02 · 73 阅读 · 0 评论 -
红黑树(AVL树的优化)下(代码实现)
解决情况一的 : cur为红,parent是红 , grandfater是黑,uncle存在且为红的情况。我们先简单的将节点找到要插入的位置,进行前后链接(先不进行调整)原创 2023-08-31 01:00:27 · 166 阅读 · 0 评论 -
红黑树(AVL树的优化)上
红黑树,是一种搜索二叉树,单在每个节点上增加一个存储位表示节点的颜色,可以是Red或Block,通过对任何一条从根到路径上各个节点着色方式的限制,红黑树确保没有一条路径会比其它路径长出两倍,因而是接近平衡的。我们上面的过程,红黑树的插入问题可能光变色就够了,插入节点之后最短并没有超过最长的2倍,也不需要旋转,降长度。有的大佬认为AVL树太过严格,对平衡的要求越严格,会带来更多的旋转(旋转也还是会有一定的消耗!4.对于每个节点,从该节点到其所有后代叶节点的简单路径上,均包含有相同的数目的黑色节点。原创 2023-08-30 00:23:16 · 137 阅读 · 0 评论 -
AVLTree深度剖析(双旋)
我们在这里的三种情况下,旋转的过程都是一样的,但是最后平衡因子的更新却是不同的,所以我们需要知道如何去区分是那种情况,好进行对应的平衡因子更新。在上一篇文章中我们提到了,单旋的情况(无论是左单旋还是右单旋),都仅仅适用于绝对的左边高或者绝对的右边高。旋完之后,形成了对称关系,我们右单旋之后,在用一次左单旋,发现又回去了!我们还有可能是在c插入的,但是还是一样的旋转过程,无非就是平衡因子的更新不同。还有一种极端情况 h==0的情况 但是旋转的过程都是不变的。这里就不做多解释了!原创 2023-07-23 20:42:14 · 124 阅读 · 0 评论 -
AVLTree深度剖析(单旋)
更新后,parent->_bf == 1 or -1 , 1代表右边高, -1代表左边高 ,这里要不要继续往上更新平衡因子的因素取决于,parent子树的高度是否变化,parent的平衡因子变为-1或者1,高度肯定的变了,为什么呢?3.更新后,parent->_bf ==0 ,说明parent插入之前的平衡因子 -1 或者 1 加加或者减减一下,说明左右子树一边高一边低,插入之后,两边一样高,说明插入填上了矮的那一边,parent所在的子树高度不变,不需要继续向上更新。原创 2023-07-18 19:54:38 · 209 阅读 · 0 评论 -
OJ题(map和set)
解法1:我们使用优先级队列 -- 仿函数来控制次数相等的时候,key的比较规则。我们应该如何控制这里的稳定,sort底层是快速排序,快速排序是不稳定的。解法二: 使用稳定排序,对次数进行排序(必须得是稳定排序)我们可以通过比较规则,实现间接稳定。我们使用sort 排序试试。原创 2023-07-14 09:34:41 · 190 阅读 · 0 评论 -
set和map
关联式容器就是数据和数据之间具有很强的关联性,底层用的就是红黑树,红黑树的底层说到底也是搜索树。这里set遍历出来的特征是有序的,因为set底层的搜索二叉树,搜索二叉树走中序是有序的。map插入的时候,插入的不在是一个数据,而是一个结构体,这个结构体的pair。我们先学set --- set的本质就是key模型 ,用于确认在不在。第一种删除不存在的时候,不会有任何问题,第二个删除不存在的时候就会删除出问题。但是count不是为了这里设计的,count的设计是为了保持接口的一致性。原创 2023-07-13 16:08:16 · 71 阅读 · 0 评论 -
二叉树前中后序的非递归实现
递归真正的缺陷是,每一个程序运行起来呢都是一个线程的形式,但是每一个线程都会有独立的栈空间,但是栈空间是很小的,当递归的深度太深容易栈溢出!当这个节点从栈当中出来时,说明这个节点的左子树都已经访问完了,此时可以访问这个节点的值和这个节点的右子树了!只要把节点从栈取出来,说明这个节点的左子树访问完了,需要访问右子树了。为什么有递归就一定有非递归呢?首先递归是有一定缺陷的。后序遍历就略微有点不一样了!原创 2023-07-09 01:05:21 · 234 阅读 · 0 评论 -
数据结构二叉树(OJ)题
我们当前这一道题的时间复杂度是O(h * N) h是树的高度,我们最坏情况就是在树的最底下找到,得递归h次,树的高度,每一次递归Find一次,Find一次的时间复杂度是O(N)最根本的原因就是下一个的递归改变的prev,只能改变下一个递归的prev,并没能改变上一个递归当中的prev!我们要想办法区分,从队列当中出队的数据是属于那一层的数据。用后序和中序构建一颗二叉树同理!原创 2023-07-08 22:14:17 · 280 阅读 · 0 评论 -
搜索树的Key和Key/Value模型
2.另一个场景 -- 统计水果出现的次数。我们还可以用搜索二叉树去解决我们之前的一道OJ题。链表相加 -->我们直接用key模型都够了。和我们的复杂链表复制的问题。原创 2023-07-06 02:09:23 · 98 阅读 · 0 评论 -
搜索二叉树
当然我们也可以把父亲传下去,这个是最普通的做法了,我们可以有更巧妙的做法。这时候我们还需要在最后找到了插入的位置时,new出来的节点,前后连接一下,找到这个空节点的父亲。我们还没有写拷贝构造,那么这里就是浅拷贝,浅拷贝针对于内置类型默认生成的是浅拷贝。需要被改进---》改进的方案就是平衡树 ----- AVL树、红黑树。我们加个引用来看看 ---- 前面的引用都不起作用,只有在最后一下。假如我们在这里要找的值是6,我们来看看递归是怎么找的。如果我们删除左右都不为空的呢?我们来验证一下Erase。原创 2023-07-05 17:21:10 · 92 阅读 · 0 评论