图基础-创造用于测试的简单图

如题。

方便起见,用邻接表,表示无向图;用邻接矩阵,表示有向图。

以下代码为C#,Java类似,可以自己完成。

ps:java和c#语言,即使实现细节不一样,基本可以完成相同的功能。比如LinkedList,java中大量用到index,c#则使用LinkedListNode辅助,都可以完成各种“风骚”操作。

虽然这里的例子没有用到,需要的同学也可以自行研究。


邻接表类(无向图):

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApp1
{
    //无向图(不考虑孤立点)邻接表表示法
    class MyTable
    {
        Node[] nodes;

        //构造方法1,获得图5-2所示图形
        public MyTable()
        {
            int n = 5;
            nodes = new Node[n];
            LinkedList<int> t;
            for (int i = 0; i < n; i++)
            {
                nodes[i] = new Node("v" + i);
            }
            t = new();
            t.AddLast(1);
            t.AddLast(2);
            t.AddLast(4);
            nodes[0].next = t;
            t = new();
            t.AddLast(0);
            t.AddLast(2);
            nodes[1].next = t;
            t = new();
            t.AddLast(0);
            t.AddLast(1);
            t.AddLast(4);
            nodes[2].next = t;
            t = new();
            t.AddLast(4);
            nodes[3].next = t;
            t = new();
            t.AddLast(0);
            t.AddLast(2);
            t.AddLast(3);
            nodes[4].next = t;
        }

        //构造方法2,获得边长为n的任意无向图
        public MyTable(int n)
        {
            LinkedList<int> t;
            int j;
            if (n == -1)
            {
                Console.WriteLine("输入图中节点的个数:");
                n = int.Parse(Console.ReadLine());
            }
            nodes = new Node[n];
            Console.WriteLine("输入每个节点的名称(每个名称回车结束)");
            for (int i = 0; i < n; i++)
            {
                nodes[i] = new Node(Console.ReadLine());
            }
            for (int i = 0; i < n; i++)
            {
                Console.WriteLine($"输入节点{nodes[i].v}的边(序号表示,每个序号回车,-1结束)");
                j = int.Parse(Console.ReadLine());
                t = new();
                do
                {
                    t.AddLast(j);
                    j = int.Parse(Console.ReadLine());
                } while (j != -1);
                nodes[i].next = t;
            }
        }

        //按构造输入的方式输出图,测试用。
        public void testShow()
        {
            foreach (var item in nodes)
            {
                Console.Write($"节点{item.v},边:");
                foreach (var item1 in item.next)
                {
                    Console.Write(item1 + "  ");
                }
                Console.WriteLine();
            }
        }
    }
    //顶点(值和指向边的指针)
    class Node
    {
        public string v;
        public LinkedList<int> next;
        public Node(string x)
        {
            v = x;
        }
    }
}

测试主类:

static void Main(string[] args)
        {
            MyTable mt;
            //mt= new MyTable();
            mt = new MyTable(5);
            mt.testShow();
        }

运行结果

默认构造:

节点v0,边:1  2  4
节点v1,边:0  2
节点v2,边:0  1  4
节点v3,边:4
节点v4,边:0  2  3

 指定节点和边的构造:

输入每个节点的名称(每个名称回车结束)
v0
v1
v2
v3
v4
输入节点v0的边(序号表示,每个序号回车,-1结束)
1
2
4
-1
输入节点v1的边(序号表示,每个序号回车,-1结束)
0
2
-1
输入节点v2的边(序号表示,每个序号回车,-1结束)
0
1
4
-1
输入节点v3的边(序号表示,每个序号回车,-1结束)
4
-1
输入节点v4的边(序号表示,每个序号回车,-1结束)
0
2
3
-1
节点v0,边:1  2  4
节点v1,边:0  2
节点v2,边:0  1  4
节点v3,边:4
节点v4,边:0  2  3

 邻接矩阵(有向图)代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApp1
{
    //有向图邻接矩阵表示法(图中至少有一条边)
    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)
        {
            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] = Console.ReadLine();
            }

            edges = new int[n,n];
            Console.WriteLine($"输入边起点(序号表示,每个序号回车,起点-1结束)");
            start = int.Parse(Console.ReadLine());
            end = int.Parse(Console.ReadLine());
            do
            {
                edges[start, end] = 1;
                Console.WriteLine($"输入边起点(序号表示,每个序号回车,起点-1结束)");
                start = int.Parse(Console.ReadLine());
                end = int.Parse(Console.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();
            }
        }
    }
}

主程序:

static void Main(string[] args)
        {
            MyMatrix mm;
            mm = new();
            //mm = new(5);
            mm.testShow();
        }

默认构造的运行结果:

顶点信息:v0  v1  v2  v3  v4
邻接矩阵:
0 0 1 0 1
1 0 0 0 0
0 1 0 1 0
0 0 0 0 0
0 0 0 1 0

用户指定图(P128图5-22)的运行结果:

输入每个节点的名称(每个名称回车结束)
v0
v1
v2
v3
v4
输入边起点(序号表示,每个序号回车,起点-1结束)
0
1
输入边起点(序号表示,每个序号回车,起点-1结束)
0
4
输入边起点(序号表示,每个序号回车,起点-1结束)
0
3
输入边起点(序号表示,每个序号回车,起点-1结束)
1
2
输入边起点(序号表示,每个序号回车,起点-1结束)
3
2
输入边起点(序号表示,每个序号回车,起点-1结束)
3
4
输入边起点(序号表示,每个序号回车,起点-1结束)
2
4
输入边起点(序号表示,每个序号回车,起点-1结束)
-1
0
顶点信息:v0  v1  v2  v3  v4
邻接矩阵:
0 1 0 1 1
0 0 1 0 0
0 0 0 0 1
0 0 1 0 1
0 0 0 0 0

关于带权图,稍作修改即可。

1、邻接表:边表节点添加一个权值字段即可(可以用元组实现,也可以用类实现);

2、邻接矩阵:无穷可以用一个极大值表示;权值直接填入对应位置即可。

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