2025-11-10
C#
00

目录

无向图
示例
有向图
示例
C#中的图表示
无向图的表示
有向图的表示
总结

图是一种复杂的数据结构,它由一组节点和连接这些节点的边组成。在编程和算法设计中,图可以用来表示网络、社交关系、地图等多种结构。图主要分为两类:有向图和无向图。

无向图

无向图是图的一种,其中边没有方向。在无向图中,边是双向的,这意味着如果存在一条边连接两个节点A和B,那么从A到B和从B到A都是可以的。无向图通常用于表示双向关系,例如社交网络中的朋友关系。

示例

考虑一个社交网络,其中的节点代表人,边代表他们之间的朋友关系。如果Alice和Bob是朋友,那么我们可以在Alice和Bob之间画一条边。

XML
Alice — Bob | \ | Charlie | Dave

在这个例子中,Alice与Bob、Charlie和Dave是朋友,而Bob与Alice是朋友,Charlie与Alice是朋友,Dave与Alice是朋友。

有向图

有向图是图的另一种形式,其中每条边都有一个方向。在有向图中,如果存在一条从节点A指向节点B的边,那么这并不意味着存在从节点B指向节点A的边。有向图经常用于表示具有方向性的关系,例如网页之间的链接关系。

示例

考虑一个任务管理系统,其中的节点代表任务,边代表任务之间的依赖关系。如果任务A依赖于任务B的完成,那么我们可以画一条从任务B指向任务A的边。

XML
TaskB → TaskA ↓ TaskC

在这个例子中,TaskA依赖于TaskB的完成,而TaskC也依赖于TaskB的完成。但这并不意味着TaskA依赖于TaskC或者TaskC依赖于TaskA。

C#中的图表示

在C#中,我们可以使用多种方式来表示图。下面是一个简单的无向图和有向图的表示方法。

无向图的表示

C#
public class Graph { // 使用字典来表示图的邻接表,键为顶点,值为与该顶点相连的顶点集合 private Dictionary<string, HashSet<string>> adjacencyList; public Graph() { adjacencyList = new Dictionary<string, HashSet<string>>(); } // 添加边 public void AddEdge(string vertex1, string vertex2) { // 如果顶点vertex1不在邻接表中,则为其创建一个新的HashSet if (!adjacencyList.ContainsKey(vertex1)) { adjacencyList[vertex1] = new HashSet<string>(); } // 如果顶点vertex2不在邻接表中,则为其创建一个新的HashSet if (!adjacencyList.ContainsKey(vertex2)) { adjacencyList[vertex2] = new HashSet<string>(); } // 在vertex1的HashSet中添加vertex2,表示vertex1到vertex2有一条边 adjacencyList[vertex1].Add(vertex2); // 因为是无向图,所以也需要在vertex2的HashSet中添加vertex1 adjacencyList[vertex2].Add(vertex1); } // 打印图 public void PrintGraph() { // 遍历邻接表的每一个顶点 foreach (var vertex in adjacencyList) { Console.Write(vertex.Key + ": "); // 遍历与该顶点相连的所有顶点,并打印 foreach (var edge in vertex.Value) { Console.Write(edge + " "); } Console.WriteLine(); } } }

调用

C#
public static void Main() { Graph graph = new Graph(); graph.AddEdge("Alice", "Bob"); graph.AddEdge("Alice", "Charlie"); graph.AddEdge("Alice", "Dave"); graph.PrintGraph(); }

image.png

有向图的表示

C#
public class Digraph { // 使用字典来表示图的邻接表,键是顶点,值是一个HashSet,包含所有从该顶点出发可以到达的顶点 private Dictionary<string, HashSet<string>> adjacencyList; public Digraph() { adjacencyList = new Dictionary<string, HashSet<string>>(); } // 添加边 public void AddEdge(string vertex1, string vertex2) { // 如果顶点vertex1不在邻接表中,则为其创建一个新的HashSet if (!adjacencyList.ContainsKey(vertex1)) { adjacencyList[vertex1] = new HashSet<string>(); } // 将vertex2添加到vertex1的邻接HashSet中,表示从vertex1可以到达vertex2 adjacencyList[vertex1].Add(vertex2); } // 打印图 public void PrintGraph() { // 遍历邻接表中的每一个顶点及其可达顶点 foreach (var vertex in adjacencyList) { Console.Write(vertex.Key + " -> "); // 遍历并打印从该顶点出发可以到达的所有顶点 foreach (var edge in vertex.Value) { Console.Write(edge + " "); } Console.WriteLine(); } } }

调用

C#
public static void Main() { Digraph digraph = new Digraph(); digraph.AddEdge("TaskB", "TaskA"); digraph.AddEdge("TaskB", "TaskC"); digraph.PrintGraph(); }

在上述代码中,我们定义了两个类GraphDigraph来分别表示无向图和有向图。这两个类使用邻接表的方式存储图,其中Dictionary用于存储每个顶点及其相邻顶点的列表。在无向图的AddEdge方法中,我们添加了两个方向的边,而在有向图的AddEdge方法中,我们只添加了一个方向的边。

总结

无向图和有向图是图论中的两个基本概念,它们在不同的应用场景中有着广泛的应用。理解它们的特点和差异对于解决实际问题非常重要。在C#中,我们可以通过创建自定义的数据结构来有效地表示和操作这些图。

本文作者:技术老小子

本文链接:

版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!