返回
图的拓扑排序:解析Kahn算法,深入理解步骤及Java实现
后端
2024-02-20 07:58:58
图的拓扑排序及其应用
在图论中,拓扑排序是指将有向无环图(DAG)的顶点排列成一个线性序列,使得对于图中任何一条有向边,从前一个顶点到后一个顶点。拓扑排序在计算机科学中有着广泛的应用,包括项目管理、任务调度和软件依赖管理等领域。
Kahn算法原理及步骤
Kahn算法是一种经典的拓扑排序算法,它利用有向无环图中顶点的入度(即指向该顶点的边的数目)来进行排序。算法的主要步骤如下:
- 初始化一个空队列Q,用于存储拓扑序列的顶点。
- 遍历图中的所有顶点,并计算每个顶点的入度。
- 将入度为0的顶点加入队列Q中。
- 重复以下步骤,直到队列Q为空:
- 从队列Q中取出一个顶点v。
- 将顶点v添加到拓扑序列中。
- 遍历顶点v的所有出边,并将其连接到的顶点的入度减1。
- 如果某个顶点的入度变为0,则将其加入队列Q中。
Java代码实现
基于邻接矩阵和邻接表的图对Kahn算法的Java实现如下:
import java.util.*;
public class TopologicalSort {
// 基于邻接矩阵的实现
public static List<Integer> topologicalSort_matrix(int[][] graph) {
int n = graph.length;
int[] inDegree = new int[n]; // 顶点的入度
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
if (graph[i][j] > 0) {
inDegree[j]++;
}
}
}
Queue<Integer> queue = new LinkedList<>(); // 存储入度为0的顶点
for (int i = 0; i < n; i++) {
if (inDegree[i] == 0) {
queue.offer(i);
}
}
List<Integer> result = new ArrayList<>(); // 存储拓扑序列
while (!queue.isEmpty()) {
int v = queue.poll();
result.add(v);
for (int i = 0; i < n; i++) {
if (graph[v][i] > 0) {
inDegree[i]--;
if (inDegree[i] == 0) {
queue.offer(i);
}
}
}
}
return result;
}
// 基于邻接表的实现
public static List<Integer> topologicalSort_list(List<List<Integer>> graph) {
int n = graph.size();
int[] inDegree = new int[n]; // 顶点的入度
for (int i = 0; i < n; i++) {
for (int j = 0; j < graph.get(i).size(); j++) {
inDegree[graph.get(i).get(j)]++;
}
}
Queue<Integer> queue = new LinkedList<>(); // 存储入度为0的顶点
for (int i = 0; i < n; i++) {
if (inDegree[i] == 0) {
queue.offer(i);
}
}
List<Integer> result = new ArrayList<>(); // 存储拓扑序列
while (!queue.isEmpty()) {
int v = queue.poll();
result.add(v);
for (int i = 0; i < graph.get(v).size(); i++) {
int next = graph.get(v).get(i);
inDegree[next]--;
if (inDegree[next] == 0) {
queue.offer(next);
}
}
}
return result;
}
public static void main(String[] args) {
// 创建一个有向无环图
int[][] graph_matrix = new int[][]{
{0, 1, 0, 0},
{0, 0, 1, 0},
{0, 0, 0, 1},
{0, 0, 0, 0}
};
List<List<Integer>> graph_list = new ArrayList<>();
for (int i = 0; i < 4; i++) {
graph_list.add(new ArrayList<>());
}
graph_list.get(0).add(1);
graph_list.get(1).add(2);
graph_list.get(2).add(3);
// 基于邻接矩阵进行拓扑排序
List<Integer> result_matrix = topologicalSort_matrix(graph_matrix);
System.out.println("基于邻接矩阵的拓扑序列:" + result_matrix);
// 基于邻接表进行拓扑排序
List<Integer> result_list = topologicalSort_list(graph_list);
System.out.println("基于邻接表的拓扑序列:" + result_list);
}
}
结束语
图的拓扑排序是图论中一项重要的技术,Kahn算法是一种高效的拓扑排序算法,本文对该算法的原理、步骤和Java实现进行了详细介绍。掌握拓扑排序的技术不仅能增强您的算法技能,还能在实际应用中解决许多问题。