如题,借助之前的简单图代码,按照书上P135算法,实现如下
图代码:
using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Text; using System.Threading.Tasks; namespace ConsoleApp3 { class MyMatrix { public string[] nodes; public int[,] edges; //构造方法1,获得图5-1所示图形 public MyMatrix() { nodes = new string[5]; edges = new int[5, 5]; for (int i = 0; i < nodes.Length; i++) { nodes[i] = "v" + i; } edges[0, 2] = 1; edges[0, 4] = 1; edges[1, 0] = 1; edges[2, 1] = 1; edges[2, 3] = 1; edges[4, 3] = 1; } //构造方法2,获得边长为n的任意有向图 public MyMatrix(int n) { StreamReader sr = new StreamReader(@"C:XX1ConsoleApp3ConsoleApp31.txt", Encoding.Default); int start, end; if (n == -1) { Console.WriteLine("输入图中节点的个数:"); n = int.Parse(Console.ReadLine()); } nodes = new string[n]; Console.WriteLine("输入每个节点的名称(每个名称回车结束)"); for (int i = 0; i < n; i++) { nodes[i] = sr.ReadLine(); } edges = new int[n, n]; Console.WriteLine($"输入边起点(序号表示,每个序号回车,起点-1结束)"); start = int.Parse(sr.ReadLine()); end = int.Parse(sr.ReadLine()); do { edges[start, end] = 1; Console.WriteLine($"输入边起点(序号表示,每个序号回车,起点-1结束)"); start = int.Parse(sr.ReadLine()); end = int.Parse(sr.ReadLine()); } while (start != -1); } //按顶点、矩阵方式输出图,测试用。 public void testShow() { Console.Write("顶点信息:"); foreach (var item in nodes) { Console.Write(item + " "); } Console.WriteLine(); Console.WriteLine("邻接矩阵:"); for (int i = 0; i < edges.GetLength(0); i++) { for (int j = 0; j < edges.GetLength(1); j++) { Console.Write(edges[i, j] + " "); } Console.WriteLine(); } } } }
数据文件1.txt:
v1 v2 v3 v4 v5 v6 v7 v8 v9 0 1 1 2 2 3 0 4 4 5 5 3 6 4 6 7 7 8 5 8 -1 -1
主程序:
static class Program { static void Main(string[] args) { //构造书上图5-25有向图 MyMatrix t = new(9); //显示,检查图是否正确 t.testShow(); //拓扑排序并显示结果 t.show(); } //拓扑排序方法(扩展方法) static void show(this MyMatrix x) { //对节点数计数 int n = x.nodes.Length,j; //标记是否打印过 bool[] flag=new bool[n]; //遍历列 for (int i = 0; i < n; i++) { //如果该列代表的节点没打印过 if(!flag[i]) { //遍历列上的边 for (j = 0; j < n; j++) { //有前驱 if(x.edges[j,i]==1) { //停止遍历该列 break; } } //如果没有前驱 if(j==n) { //打印节点 Console.Write(x.nodes[i] + " "); //设置为已打印 flag[i] = true; //删除它为起点的边 for (j = 0; j < n; j++) { x.edges[i, j] = 0; } //从头开始遍历列 i = 0; } } } } }
运行结果:
顶点信息:v1 v2 v3 v4 v5 v6 v7 v8 v9 邻接矩阵: 0 1 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 v1 v2 v3 v7 v5 v6 v4 v8 v9
(未详尽说明部分与《单源最短路径-邻接表无向网络》相同)