• 第6章 图


    6.1.3 图的基本操作

        //Graph node class
        public class GraphNode<T>
        {
            public T Value { get; set; }
    
            public GraphNode(T value)
            {
                Value = value;
            }
        }
    
        //Actions of graph
        public interface IGraph<T>
        {
            int NodeNum { get; }
            int EdageNum { get; }
    
            int IsNode(GraphNode<T> node);
            bool SetNode(GraphNode<T> node);
            bool DelNode(GraphNode<T> node);
    
            bool SetEdge(GraphNode<T> node1, GraphNode<T> node2, int value);
            bool DelEdge(GraphNode<T> node1, GraphNode<T> node2);
            bool IsEdge(GraphNode<T> node1, GraphNode<T> node2);
        }

    6.2 图的存储结构

    6.2.1 邻接矩阵

    邻接矩阵用两个数组来表示图,一个数组是一维数组,存储图中顶点的信息,一个数组是二维数组,即矩阵,存储顶点之间的信息。

        public class GraphMatrix<T> : IGraph<T>
        {
            private GraphNode<T>[] nodeArray;
            private int[,] edageArray;
    
            public int NodeNum { get; private set; }
            public int EdageNum { get; private set; }
    
            public GraphMatrix(int length)
            {
                nodeArray = new GraphNode<T>[length];
                edageArray = new int[length, length];
            }
    
            public int IsNode(GraphNode<T> node)
            {
                for (int i = 0; i < NodeNum; i++)
                {
                    if (node == nodeArray[i])
                        return i;
                }
    
                return -1;
            }
    
            public bool SetNode(GraphNode<T> node)
            {
                if (NodeNum >= nodeArray.Length)
                    return false;
    
                //If the node is already in the array, return false
                if (IsNode(node) != -1)
                    return false;
    
                nodeArray[NodeNum] = node;
                NodeNum++;
                return true;
            }
    
            public bool DelNode(GraphNode<T> node)
            {
                int index = IsNode(node);
    
                //If the node was not in node array, return false
                if (index == -1)
                    return false;
    
                //move the last node to the deleted node option
                nodeArray[index] = nodeArray[NodeNum - 1];
                for (int i = 0; i < NodeNum; i++)
                {
                    if (edageArray[index, i] != 0)
                        EdageNum -= 1;
    
                    if (edageArray[i, index] != 0)
                        EdageNum -= 1;
    
                    edageArray[index, i] = edageArray[NodeNum - 1, i];
                    edageArray[i, index] = edageArray[i, NodeNum - 1];
                }
    
                edageArray[index, index] = 0;
                for (int i = 0; i < NodeNum; i++)
                {
                    if (edageArray[NodeNum - 1, i] != 0)
                        edageArray[NodeNum - 1, i] = 0;
    
                    if (edageArray[i, NodeNum - 1] != 0)
                        edageArray[i, NodeNum - 1] = 0;
                }
                NodeNum -= 1;
    
                return true;
            }
    
            public bool SetEdge(GraphNode<T> node1, GraphNode<T> node2, int value)
            {
                int index1 = IsNode(node1);
                int index2 = IsNode(node2);
    
                //Input node was not exist in node array
                if (index1 == -1 || index2 == -1)
                    return false;
    
                if (edageArray[index1, index2] == 0)
                    EdageNum += 1;
    
                edageArray[index1, index2] = value;
    
                return true;
            }
    
            public bool DelEdge(GraphNode<T> node1, GraphNode<T> node2)
            {
                int index1 = IsNode(node1);
                int index2 = IsNode(node2);
    
                //Input node was not exist in node array
                if (index1 == -1 || index2 == -1)
                    return false;
    
                if (edageArray[index1, index2] != 0)
                {
                    EdageNum -= 1;
                    edageArray[index1, index2] = 0;
                    return true;
                }
                else
                    //There is no edage between the two input nodes
                    return false;
            }
    
            public bool IsEdge(GraphNode<T> node1, GraphNode<T> node2)
            {
                int index1 = IsNode(node1);
                int index2 = IsNode(node2);
    
                //The input node was not in the node array
                if (index1 == -1 || index2 == -1)
                    return false;
    
                if (edageArray[index1, index2] != 0)
                    return true;
                else
                    return false;
            }
    
            public void PrintMatrix()
            {
                Console.Write("  ");
    
                for (int i = 0; i < NodeNum; i++)
                {
                    if (i == 0)
                        Console.Write("| ");
    
                    Console.Write(nodeArray[i].Value);
                    Console.Write(" ");
                }
                Console.WriteLine();
    
                Console.WriteLine("--+" + string.Empty.PadRight((NodeNum + 1) * 2, '-'));
    
                for (int i = 0; i < NodeNum; i++)
                {
                    Console.Write(nodeArray[i].Value);
                    Console.Write(" ");
    
                    for (int j = 0; j < NodeNum; j++)
                    {
                        if (j == 0)
                            Console.Write("| ");
                        Console.Write(edageArray[i, j]);
                        Console.Write(" ");
                    }
                    Console.WriteLine();
                    Console.WriteLine("  |");
                }
            }
        }


    邻接矩阵类型的测试:

    using GraphObject;
    using Microsoft.VisualStudio.TestTools.UnitTesting;
    
    namespace ConsoleApp
    {
        class Program
        {
            static void Main(string[] args)
            {
                GraphMatrix<int> matrix = new GraphMatrix<int>(100);
    
                //Inial graph object
                GraphNode<int> node1 = new GraphNode<int>(1);
                GraphNode<int> node2 = new GraphNode<int>(2);
                GraphNode<int> node3 = new GraphNode<int>(3);
                GraphNode<int> node4 = new GraphNode<int>(4);
                GraphNode<int> node5 = new GraphNode<int>(5);
                GraphNode<int> node6 = new GraphNode<int>(6);
                GraphNode<int> node7 = new GraphNode<int>(7);
                GraphNode<int> node8 = new GraphNode<int>(8);
    
                matrix.SetNode(node1);
                matrix.SetNode(node2);
                matrix.SetNode(node3);
                matrix.SetNode(node4);
                matrix.SetNode(node5);
                matrix.SetNode(node6);
                matrix.SetNode(node7);
                matrix.SetNode(node8);
    
                matrix.SetEdge(node2, node1, 2);
                matrix.SetEdge(node3, node1, 3);
                matrix.SetEdge(node2, node3, 4);
                matrix.SetEdge(node3, node4, 5);
                matrix.SetEdge(node5, node6, 4);
                matrix.SetEdge(node8, node6, 1);
    
                Assert.AreEqual<int>(8, matrix.NodeNum);
                Assert.AreEqual<int>(6, matrix.EdageNum);
    
                //Scenario 1: Test add new node
                GraphNode<int> node9 = new GraphNode<int>(9);
                matrix.SetNode(node9);
                matrix.SetEdge(node9, node5, 3);
                matrix.SetEdge(node9, node8, 1);
                matrix.SetEdge(node6, node9, 2);
    
                Assert.AreEqual<int>(9, matrix.NodeNum);
                Assert.AreEqual<int>(9, matrix.EdageNum);
    
                //Scenario 2: Test remove node
                matrix.DelNode(node8);
                Assert.AreEqual<int>(8, matrix.NodeNum);
                Assert.AreEqual<int>(7, matrix.EdageNum);
    
                matrix.SetNode(node8);
                matrix.SetEdge(node8, node6, 1);
                matrix.SetEdge(node9, node8, 1);
                Assert.AreEqual<int>(9, matrix.NodeNum);
                Assert.AreEqual<int>(9, matrix.EdageNum);
    
                //Scenario 3: Test add/remove new edage
                matrix.DelEdge(node3, node4);
                Assert.AreEqual<int>(9, matrix.NodeNum);
                Assert.AreEqual<int>(8, matrix.EdageNum);
                matrix.SetEdge(node3, node4, 5);
                Assert.AreEqual<int>(9, matrix.NodeNum);
                Assert.AreEqual<int>(9, matrix.EdageNum);
    
                //Scenario 4: Other medthods
                Assert.IsTrue(matrix.IsNode(node4) >= 0, "node4 should be exist in matrix");
                Assert.IsFalse(matrix.IsNode(new GraphNode<int>(10)) >= 0, "node4 should not be exist in matrix");
                Assert.IsTrue(matrix.IsEdge(node3, node1), "edage should be exist in matrix");
                Assert.IsFalse(matrix.IsEdge(node3, node2), "edage should not be exist in matrix");
            }
        }
    }
    


     邻接矩阵存储图的类的模型图:

    邻接矩阵存储图的类的关系图:

  • 相关阅读:
    java JDBC (一)
    java 线程(七)等待与唤醒
    java 线程(六)死锁
    java 线程(五)线程安全 Lock接口
    java 线程(四)线程安全 同步方法
    查询计算机启动了多长时间的工具
    查询计算机启动了多长时间的工具
    百度同步盘无法登陆,报错155010,对策
    百度同步盘无法登陆,报错155010,对策
    锁屏工具,解决三星S7迷你锁屏后不能通过指纹解锁的问题
  • 原文地址:https://www.cnblogs.com/james1207/p/3301757.html
Copyright © 2020-2023  润新知