第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");
        }
    }
}


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

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

原文地址:https://www.cnblogs.com/james1207/p/3301757.html