邻接矩阵有向图拓扑排序

如题,借助之前的简单图代码,按照书上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

(未详尽说明部分与《单源最短路径-邻接表无向网络》相同)

原文地址:https://www.cnblogs.com/wanjinliu/p/14188686.html