Arian Soleimanzadeh
  • 首页
  • 博客
  • 播客
  • 视频
  • 联系
العربيةArabic
DeutschGerman
EnglishEnglish
فارسیPersian
한국어Korean
中文Chinese
面板•快速联系

Languages

Choose your interface locale

ar

العربية

Arabic

de

Deutsch

German

en

English

English

fa

فارسی

Persian

ko

한국어

Korean

zh

中文

Chinese

预约咨询

发送一条简短消息——我会尽快回复。

LinkedIn快速回复
首页/文章/什么是 Kosaraju 算法?它解决了什么问题?
Kosaraju文章

什么是 Kosaraju 算法?它解决了什么问题?

从零理解 Kosaraju 算法:什么是强连通分量(SCC)、为什么普通 DFS 不够、算法的核心思想,以及它在软件依赖、微服务和网络分析中的实际应用。

2026年8月19日8 分钟阅读4 浏览
#Kosaraju#Graph Algorithms#Strongly Connected Components#SCC#DFS#Directed Graph#Algorithms#Software Engineering

Arian Soleimanzadeh

Software Engineer & Researcher

展示 Kosaraju 算法和有向图强连通分量的概念图

Arian Soleimanzadeh

AI · 代码 · 产品

研究 + 工程
本页目录
引言什么是图?什么是有向图?问题从哪里开始?Strongly Connected 是什么意思?什么是强连通分量?Kosaraju 算法做什么?为什么 SCC 很重要?1. 检测循环依赖2. 微服务架构3. 社交网络4. 网页链接分析5. 编译器与程序分析6. 包依赖系统为什么普通 DFS 不够?Kosaraju 的核心思想第一步:第一次 DFS第二步:反转所有边第三步:再次执行 DFS一个简单例子时间复杂度还有其他 SCC 算法吗?什么情况下应该想到 Kosaraju?Cycle 和 SCC 有什么区别?总结

引言

很多图算法第一次接触时似乎非常复杂,但它们通常都在解决一个容易理解的问题。Kosaraju 算法就是一个典型例子。

Kosaraju 算法用于在有向图中寻找 Strongly Connected Components,也就是强连通分量(SCC)。

本文不会一开始就进入数学证明或代码实现,而是先理解它到底要解决什么问题。


什么是图?

图由一组顶点以及连接这些顶点的边组成。

例如:

Code
123
A --- B
|     |
C --- D

图可以用来描述许多现实系统,例如:

  • 社交网络
  • 城市道路
  • 服务器之间的通信
  • 软件包依赖关系
  • 网页之间的链接
  • 程序执行流程
  • 微服务之间的调用关系

什么是有向图?

有向图中的边具有方向。

例如:

Code
1
A → B

意味着可以从 A 到达 B,但不一定能够从 B 返回 A。

在软件系统中:

Code
1
Service A → Service B

可以表示 Service A 依赖 Service B。


问题从哪里开始?

考虑下面的图:

Code
12345
A → B → C
↑       ↓
└───────┘

D → E

我们可以从 A 到 B,从 B 到 C,再从 C 回到 A。

因此:

Code
1
{A, B, C}

构成了一个关系非常紧密的顶点集合。

但是:

Code
1
D → E

只能从 D 到 E,却无法从 E 返回 D。


Strongly Connected 是什么意思?

如果两个顶点 u 和 v 同时满足:

Code
1
u → ... → v

以及:

Code
1
v → ... → u

那么它们就是强连通的。

换句话说,两者必须能够互相到达。


什么是强连通分量?

Strongly Connected Component(SCC) 是有向图中的一个最大顶点集合,其中任意一个顶点都可以到达集合中的其他所有顶点。

例如:

Code
1234567
A → B → C
↑       ↓
└───────┘

D → E → F
↑       ↓
└───────┘

这里存在两个 SCC:

Code
12
SCC 1 = {A, B, C}
SCC 2 = {D, E, F}

Kosaraju 算法做什么?

Kosaraju 的任务就是找到有向图中的所有强连通分量。

例如:

Code
123456
A → B
B → C
C → A
C → D
D → E
E → D

输出为:

Code
12
SCC 1 = {A, B, C}
SCC 2 = {D, E}

可以简单地定义为:

Kosaraju 算法把有向图划分成若干最大顶点组,使得同一组中的顶点可以沿着有向路径互相到达。


为什么 SCC 很重要?

1. 检测循环依赖

例如:

Code
123
Module A → Module B
Module B → Module C
Module C → Module A

这是一个 Circular Dependency。

这三个模块属于同一个 SCC。

2. 微服务架构

如果多个服务之间形成循环调用关系,SCC 分析可以帮助识别这些紧密耦合的服务组。

3. 社交网络

可以把用户表示为顶点,把关注关系表示为有向边,然后分析彼此可达的用户群体。

4. 网页链接分析

网页是顶点,超链接是有向边。SCC 可以帮助识别能够通过链接互相访问的一组页面。

5. 编译器与程序分析

Control Flow Graph、Call Graph 和 Dependency Graph 中可能存在循环结构,SCC 可以用于识别这些结构。

6. 包依赖系统

大型项目中的库和软件包可能出现循环依赖,SCC 算法可以有效识别这些依赖组。


为什么普通 DFS 不够?

考虑:

Code
1
A → B → C

从 A 执行 DFS 可以访问 A、B、C。

但它们并不是同一个 SCC,因为 C 无法返回 B 或 A。

因此:

Code
1
Reachability ≠ Strong Connectivity

仅仅能够到达并不代表强连通。

Kosaraju 通过特殊的访问顺序以及反向图解决这个问题。


Kosaraju 的核心思想

从高层来看,算法分为三个步骤。

第一步:第一次 DFS

在原图上执行 DFS,并记录顶点完成处理的顺序。

第二步:反转所有边

构造 Transpose Graph。

如果原图中有:

Code
1
A → B

反向图中就是:

Code
1
A ← B

第三步:再次执行 DFS

按照第一次 DFS 得到的特殊顺序,在反向图上再次运行 DFS。

第二阶段中每次独立的 DFS 都会得到一个 SCC。

整体过程可以表示为:

Code
1234567891011
Original Graph
      ↓
     DFS
      ↓
Finish Order
      ↓
Transpose Graph
      ↓
     DFS
      ↓
     SCCs

后续文章会进一步解释为什么这种方法在数学上是正确的。


一个简单例子

Code
1234567
A → B → C
↑       ↓
└───────┘

C → D
D → E
E → D

可以得到:

Code
12
SCC 1 = {A, B, C}
SCC 2 = {D, E}

虽然 C 可以到达 D,但 D 和 E 无法返回 A、B、C,因此它们不能属于同一个 SCC。


时间复杂度

使用邻接表时,Kosaraju 的时间复杂度为:

Code
1
O(V + E)

其中:

  • V 是顶点数量。
  • E 是边的数量。

因此,该算法即使处理较大的图也十分高效。


还有其他 SCC 算法吗?

有。常见算法包括:

  • Tarjan's Algorithm
  • Gabow's Algorithm

Tarjan 同样可以在 O(V + E) 时间内运行。

不过 Kosaraju 的两阶段结构相对直观,因此非常适合作为学习 SCC 的第一种算法。


什么情况下应该想到 Kosaraju?

如果有向图问题中出现以下关键词,通常应该考虑 SCC:

  • Strong Connectivity
  • Mutual Reachability
  • Circular Dependency
  • 循环模块依赖
  • 循环服务依赖
  • 有向图分量

Cycle 和 SCC 有什么区别?

Cycle 是一个闭合路径,例如:

Code
1
A → B → C → A

而 SCC 是一个最大的互相可达顶点集合。

一个 SCC 内部可能包含多个不同的环。

所以 SCC 描述的是比单个 Cycle 更完整的结构。


总结

Kosaraju 算法用于寻找有向图中的 Strongly Connected Components。

SCC 是一个最大顶点集合,其中每个顶点都可以通过有向路径到达其他所有顶点。

这一概念可以应用于软件依赖分析、微服务架构、社交网络、编译器、网页图以及包管理系统等领域。

Kosaraju 使用两次 DFS 和一个 Transpose Graph,在邻接表表示下时间复杂度为 O(V + E)。

最重要的一点是:

Kosaraju 不只是用来检测某一个环,它用于揭示有向图的内部结构,并把图划分为最大的互相可达顶点组。

下一篇文章将深入介绍 Strongly Connected Components,为后续逐步分析 Kosaraju 的执行过程做好准备。

本页目录
引言什么是图?什么是有向图?问题从哪里开始?Strongly Connected 是什么意思?什么是强连通分量?Kosaraju 算法做什么?为什么 SCC 很重要?1. 检测循环依赖2. 微服务架构3. 社交网络4. 网页链接分析5. 编译器与程序分析6. 包依赖系统为什么普通 DFS 不够?Kosaraju 的核心思想第一步:第一次 DFS第二步:反转所有边第三步:再次执行 DFS一个简单例子时间复杂度还有其他 SCC 算法吗?什么情况下应该想到 Kosaraju?Cycle 和 SCC 有什么区别?总结

文章信息

发布时间、阅读时长和浏览数据。

发布

2026年8月19日

更新

2026年8月20日

阅读时长

8 分钟阅读

浏览

4

作者

Arian Soleimanzadeh

上一篇

什么是 Longest Common Substring?使用动态规划寻找最长公共子串

下一篇

什么是汉明距离(Hamming Distance)?从原理到实现与实际应用

让我们构建清晰、快速而优雅的作品。

用于合作、咨询或产品工作的快速联系入口。

快速联系给我发邮件
Arian Soleimanzadeh

个人作品集,聚焦现代 Web 工程、UI 系统与实用型 AI 产品——干净的代码,清晰的设计。

快速链接

  • 关于
  • 博客
  • 项目
  • 联系

联系

  • info@ariansoleimanzadeh.site
  • soleimanzadeh.a.work@gmail.com

可联系时间: 工作日

通常回复时间在 24小时内。

订阅通讯

获取文章、项目与新版本发布的更新。

© 2026 ariansoleimanzadeh.site — 保留所有权利。

LinkedIn