zoukankan      html  css  js  c++  java
  • 邻接矩阵有向图拓扑排序

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

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

  • 相关阅读:
    关于基础排序算法的思考--插入排序
    关于购物车的多层复选全选
    随便写写
    第一篇小博文
    C# 遍历目录下所有文件方法
    C#驱动MongoDB官方中查询条件Query用法
    mongodb 修改远程连接
    Python 爬虫练习低调163疫情数据辽宁地图
    jquery easyui datagrid drop事件执行顺序
    https request报错 ServicePointManager.SecurityProtocol 搞定
  • 原文地址:https://www.cnblogs.com/wanjinliu/p/14188686.html
Copyright © 2011-2022 走看看