- 博客(19)
- 收藏
- 关注
原创 深入浅出并查集(不相交集合实现思路)
并查集是一种非常高效的数据结构,适用于处理不相交集合的合并与查找问题。通过从数组到树结构,再到加权树和路径压缩的演进,我们不断优化了并查集的性能。最终,路径压缩技术使得并查集的操作时间复杂度接近O(1),非常适合处理大规模数据。
2025-02-02 12:47:36
736
原创 Prim算法最小生成树介绍(图文分析)
Prim算法像是从一个顶点开始延伸生长的树,但是选择边的时候要从全局考虑,而不是只考虑当前顶点,因为树的生长方向未必从当前顶点开始
2025-01-19 16:00:25
802
原创 有向图强连通分量(kosaraju算法图文分析)
逆后序遍历(也即拓扑排序)保证了当我们处理一个节点时(图2中的C),它的所有后继节点(图2中的D和E)已经被处理过。这对于确保在转置图中从正确的起点开始进行第二次DFS非常重要。
2025-01-11 21:18:25
840
原创 拓扑排序(Kahn算法和DFS算法)
通过反转后续遍历得到的结果,我们可以确保对于每条有向边 (u, v),顶点 u 总是出现在顶点 v 之前,从而满足拓扑排序的条件。
2025-01-05 21:08:13
786
原创 有向图检测环(DFS思路分析)
我们知道DFS使用的是递归,在执行递归函数时,系统使用递归栈存储每次函数调用的相关信息,一旦发现某个路径走完了(比如A->C),那么就将当前的调用弹出递归栈,然后将下一个路径压栈(比如A->B->D->A)。
2025-01-03 16:04:44
666
原创 一文读懂Dijkstra(迪克斯特拉)单源最短路径算法
划重点:这三个概念很重要,选中的节点就是当前dist最小的节点(目前是V2,因为V1已经处理过,不包含V1),未处理的节点就是已经计算出dist,但是不是目前的最短路径的节点(V6,V3),已处理过的节点就是曾经成为最短路径的节点(V1)。
2024-12-29 09:20:00
897
原创 使用栈模拟双路递归
在使用递归的时候可能会出现StackOverflow,为了防止这种情况,可以使用栈来代替递归,递归的本质也是栈,只不过在递归过程中,入栈的对象实际上是整个函数调用的执行上下文,而手动使用栈的时候,入栈的对象需要我们自己控制。3 下一轮循环,栈顶01234弹栈,分成两部分,右侧部分234先压栈,左侧01再压栈。7下一轮循环,栈顶234弹栈,分成两部分,右侧部分34先压栈,左侧2再压栈。4 下一轮循环,栈顶01弹栈,分成两部分,右侧部分1先压栈,左侧0再压栈。5 下一轮循环,栈顶0弹栈,长度为1,打印。
2024-12-21 14:59:11
359
原创 设计模式5大原则总结
通过依赖抽象,而不是具体的实现,软件系统能够更好地适应变化,减少修改引发的连锁效应,实现开闭原则的核心思想。综上所述,遵循开闭原则能够促进软件工程中的良好实践,确保软件随着时间推移仍能保持良好的结构和健康的生命力,进而提升软件的整体质量和开发团队的,因此,在代码设计时就要考虑以后的功能扩展,典型的应用有策略模式、装饰者模式等。:比如策略模式中的上下文,执行策略的方法接受的是策略的抽象接口,这样只要客户端传入不同的具体策略,上下文就能执行相应策略的方法,而无需修改上下文,轻松实现替换或新增具体实现类。
2024-05-06 18:49:29
689
原创 状态模式和策略模式的区别
状态模式的状态可以存储上下文,策略类不关心上下文状态模式的状态之间可以相互依赖,策略类之间相互独立状态模式可以替换上下文中的状态(将上下文对象的状态this替换为其它状态),策略类不行策略类处理单个特定的任务,状态类为上下文对象提供所有对应状态的实现策略通常作为参数传递给上下文,状态可以由上下文自身创建
2024-04-08 23:02:07
320
原创 策略模式和命令模式的区别
策略模式主要针对算法抽象(Strategy策略接口),它将每个算法封装到一个单独的类中,使得客户端可以根据具体情况在这些策略之间进行切换,策略模式关注的是定义一系列可互换的算法或行为,允许在运行时选择和替换不同的策略。而命令模式则是针对请求抽象(Command命令接口),Command通过将任何操作转换为对象,操作的参数将成为该对象的字段。从而实现使得请求可以被存储、延迟、排队、撤销、重试以及发送到远程服务器等。策略模式侧重于不同策略类实现与切换,而命令模式则侧重于对(不同)请求的封装
2024-04-06 15:12:32
490
原创 策略模式中的上下文你可能用错了
通常情况使用策略模式,客户端通常不会主动调用上下文包装的的调用策略对象的方法,而是把策略对象交给上下文,让上下文在适当的情况下调用。这样一来,客户端就不需要关注具体策略的实现细节,它只负责决定使用哪种策略以及何时将其传递给上下文。上下文则承担起与策略对象交互的责任,确保在正确的上下文中执行策略对象的方法。这样的设计有助于降低耦合度,提高代码的可扩展性和重用性。
2024-04-02 17:36:16
315
原创 一个例子读懂享元模式
通过上面的例子可以发现,享元模式实际上是缓存了可以重用的部分,在本例中就是Shap对象,这种情况下主要是减少形状对象(Shap)的创建,从而较少了内存的消耗。鉴别是否可以用享元模式,需要确认可共享的部分是有限的并且大量重复出现的其次,共享部分通常被设计为不可变的
2024-04-01 17:17:08
369
原创 建造者模式和工厂模式的区别
建造者模式更关注对象的构建过程,适合于创建对象的内部结构复杂、组成部分及其装配顺序可变的情况,而工厂模式更关注的是对象的类型
2024-04-01 11:28:57
593
原创 代理模式和装饰器模式的区别
对于代理模式,客户端可以无需知道目标对象的存在,目标对象的生命周期则交给代理对象来处理。而对于装饰器模式来说,目标对象对于客户端来说是可见的,并且能够脱离装饰器独立工作,客户端可以无需知道装饰器的存在。
2024-03-26 11:26:57
798
原创 JDK动态代理原理浅析(通俗易懂版)
与静态代理相比,动态代理只需要指定增强方法,运行时会应用于所有的被代理类实现的接口方法上(如果需要指定方法增强,可以在invoke方法中判断method的name来制定增强),减少了代码量,并且后续如果被代理类后续要增加接口也无需更改代码,符合开闭原则。我们先执行增强方法,然后通过调用被代理对象的方法来实现代理功能。众所周知,静态代理模式就是通过代理类和被代理类实现相同的接口,代理类持有被代理类的对象,然后在代理类实现的方法中通过在调用被代理类的方法前后执行增强代码来实现。结果如下,确实实现了代理的功能。
2024-03-23 13:38:05
654
原创 JAVA通过阶乘案例理解递归算法
是不是思路清晰一些了,不是在调用的过程中计算的,而是在返回的途中进行的计算,这个例子是返回时进行的运算,还有一些是在调用过程中进行的运算,返回了就不再运算了,有些类似循环。直到现在,所有的recursion方法都没有返回值,所以,都在等待一个具体的返回值,好了,终于到了最里层。4*recursion(3)也有了具体的返回值,变成了3*2,并返回24。3*recursion(2)也有了具体的返回值,变成了3*2,并返回6。,变成了2*1,并返回2。
2023-04-16 15:15:27
126
1
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人