c#实现图的拓扑排序、深度优先、广度优先两种算法
原文链接:https://blog.csdn.net/MfuuJava/article/details/132933517
拓扑排序是一种在有向无环图(DAG)中对节点进行排序的算法。
在 C# 中,我们可以使用深度优先搜索(DFS)和拓扑排序算法来解决这个问题。
深度优先代码:
using System; using System.Collections.Generic; class Graph { private int V; // 图中节点的数量 private List<List<int>> adj; // 邻接列表 // 构造函数 public Graph(int v) { V = v; adj = new List<List<int>>(v); for (int i = 0; i < v; ++i) adj.Add(new List<int>()); } // 添加边 public void AddEdge(int v, int w) { adj[v].Add(w); } // 拓扑排序的辅助函数 private void TopologicalSortUtil(int v, bool[] visited, Stack<int> stack) { visited[v] = true; foreach (int i in adj[v]) { if (!visited[i]) TopologicalSortUtil(i, visited, stack); } stack.Push(v); } // 执行拓扑排序 public void TopologicalSort() { Stack<int> stack = new Stack<int>(); bool[] visited = new bool[V]; for (int i = 0; i < V; i++) visited[i] = false; for (int i = 0; i < V; i++) { if (visited[i] == false) TopologicalSortUtil(i, visited, stack); } // 打印排序结果 while (stack.Count > 0) { Console.Write(stack.Pop() + " "); } } // 测试 public static void Main(string[] args) { Graph graph = new Graph(6); graph.AddEdge(5, 2); graph.AddEdge(5, 0); graph.AddEdge(4, 0); graph.AddEdge(4, 1); graph.AddEdge(2, 3); graph.AddEdge(3, 1); Console.WriteLine("拓扑排序结果:"); graph.TopologicalSort(); Console.ReadKey(); } }
在上述代码中,我们首先定义了一个 Graph 类,用于表示有向无环图。Graph 类包含了图中节点的数量和一个邻接列表 adj,用于存储图的边。
我们使用 AddEdge 方法向图中添加边。然后,在 TopologicalSortUtil 方法中,我们使用搜索来遍历图,并将访问过的节点压入栈中。
最后,在 TopologicalSort 方法中,我们遍历图中的所有节点,并调用 TopologicalSortUtil 方法进行拓扑排序。最终,我们打印栈中的元素,即可得到拓扑排序的结果。
在上述示例中,我们创建了一个包含6个节点的图,并添加了一些边。然后,我们执行拓扑排序,并打印排序结果。
广度优先:
using System; using System.Collections.Generic; public class Graph { private int V; //图中节点的个数 private List<int>[] adj; //图的邻接表 public Graph(int v) { V = v; adj = new List<int>[v]; for (int i = 0; i < v; ++i) adj[i] = new List<int>(); } public void AddEdge(int v, int w) { adj[v].Add(w); //将节点w加入节点v的邻接表中 } public void TopologicalSort() { int[] indegree = new int[V]; //用于统计每个节点的入度 for (int i = 0; i < V; ++i) indegree[i] = 0; //统计每个节点的入度 for (int v = 0; v < V; ++v) { List<int> adjList = adj[v]; foreach (int w in adjList) indegree[w]++; } Queue<int> queue = new Queue<int>(); //存放入度为0的节点 for (int i = 0; i < V; ++i) { if (indegree[i] == 0) queue.Enqueue(i); } List<int> result = new List<int>(); //存放排序结果 int count = 0; //已经排序的节点个数 while (queue.Count > 0) { int v = queue.Dequeue(); result.Add(v); count++; //将与节点v相邻的节点的入度减1 List<int> adjList = adj[v]; foreach (int w in adjList) { indegree[w]--; if (indegree[w] == 0) queue.Enqueue(w); } } //判断是否有环 if (count != V) { Console.WriteLine("图中存在环!"); return; } //输出排序结果 Console.WriteLine("拓扑排序结果:"); foreach (int v in result) { Console.Write(v + " "); } } } public class Program { public static void Main(string[] args) { Graph g = new Graph(6); g.AddEdge(5, 2); g.AddEdge(5, 0); g.AddEdge(4, 0); g.AddEdge(4, 1); g.AddEdge(2, 3); g.AddEdge(3, 1); g.TopologicalSort(); Console.ReadKey(); } }
using System; using System.Collections.Generic; public class TopologicalSort { private Dictionary<char, HashSet<char>> graph; private Dictionary<char, int> inDegrees; public TopologicalSort(Dictionary<char, HashSet<char>> graph) { this.graph = graph; inDegrees = new Dictionary<char, int>(); foreach (var vertex in graph.Keys) { if (!inDegrees.ContainsKey(vertex)) { inDegrees[vertex] = 0; } foreach (var neighbor in graph[vertex]) { if (!inDegrees.ContainsKey(neighbor)) { inDegrees[neighbor] = 0; } inDegrees[neighbor]++; } } } public List<char> Sort() { Queue<char> sources = new Queue<char>(); List<char> sorted = new List<char>(); foreach (var vertex in inDegrees.Keys) { if (inDegrees[vertex] == 0) { sources.Enqueue(vertex); } } while (sources.Count > 0) { char vertex = sources.Dequeue(); sorted.Add(vertex); foreach (var neighbor in graph[vertex]) { inDegrees[neighbor]--; if (inDegrees[neighbor] == 0) { sources.Enqueue(neighbor); } } } if (sorted.Count != inDegrees.Count) { throw new InvalidOperationException("Graph has a cycle"); } return sorted; } } // 使用示例 public class Program { public static void Main() { var graph = new Dictionary<char, HashSet<char>>() { { 'A', new HashSet<char>() { 'B', 'C' } }, { 'B', new HashSet<char>() { 'D', 'E' } }, { 'C', new HashSet<char>() { 'F' } }, { 'D', new HashSet<char>() { 'E' } }, { 'E', new HashSet<char>() { 'F' } }, { 'F', new HashSet<char>() { } } }; TopologicalSort topologicalSort = new TopologicalSort(graph); List<char> sorted = topologicalSort.Sort(); foreach (char vertex in sorted) { Console.WriteLine(vertex); } } }