图的表示方式----邻接矩阵、邻接表

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

namespace Maze
{
    /// <summary>
    /// 图的顶点
    /// </summary>
    class Vertex
    {
        public string Name;
        public int InDegree;
        public int OutDegree;
        public Vertex NextVertex;    //嵌套定义(相对采用指针消耗更大内存),下一个顶点,用于邻接表
        public Vertex(string name)
        {
            Name = name;
            InDegree = 0;
            OutDegree = 0;
            NextVertex = null;
        }
    }


    /// <summary>
    ///  邻接矩阵表示图
    /// </summary>
    class Graphic_Matrix
    {
        private int Capacity;            //图的容量
        private bool IsDirection;        //图是否有向标志
        public Vertex[] VertexList;     //图中顶点数组
        public int[,] AdjacencyMat;     //图的邻接矩阵
        public int Size;                //当前图中顶点数目

        /// <summary>
        /// 邻接矩阵图的初始化
        /// </summary>
        /// <param name="Max_Size">图的最大容量</param>
        /// <param name="Direction_bool">有向标志</param>
        public Graphic_Matrix(int Max_Size,bool Direction_bool)
        {
            Capacity = Max_Size;
            IsDirection = Direction_bool;
            VertexList = new Vertex[Max_Size];
            AdjacencyMat = new int[Max_Size, Max_Size];
            Size = 0;
            for (int i = 0; i < Max_Size; i++)
            {
                for (int j = 0; j < Max_Size; j++)
                {
                    AdjacencyMat[j, i] = 0;
                }
            }
        }

        /// <summary>
        /// 向图中添加顶点
        /// </summary>
        /// <param name="vertex">待添加的顶点</param>
        public void AddVertex(Vertex vertex)
        {
            if (GetIndex(vertex) == -1)    //确保该顶点未添加
            {
                if (Size < Capacity)
                {
                    VertexList[Size++] = vertex;
                }
                else                      //超容量
                {
                    throw new Exception("The graphic is full!");
                }
            }
        }

        /// <summary>
        /// 以顶点的方式添加边
        /// </summary>
        /// <param name="StartVertex">边的起点</param>
        /// <param name="EndVertex">边的终点</param>
        public void AddEdge(Vertex StartVertex, Vertex EndVertex)
        {
            int Index1, Index2;
            AddVertex(StartVertex);    //添加该顶点,若图中已有该顶点,则会直接返回
            Index1 = GetIndex(StartVertex);
            AddVertex(EndVertex);
            Index2 = GetIndex(EndVertex);
            AddEdge(Index1, Index2);
        }

        /// <summary>
        /// 以内部编号添加顶点
        /// </summary>
        /// <param name="StartIndex">起点的内部编号</param>
        /// <param name="Index2">终点的内部编号</param>
        public void AddEdge(int StartIndex, int EndIndex)
        {
            if (StartIndex < Size && EndIndex < Size)    //确保该顶点已经添加在图中
            {
                AdjacencyMat[StartIndex, EndIndex] = 1;
                VertexList[StartIndex].OutDegree++;
                VertexList[EndIndex].InDegree++;
                if (!IsDirection)                  //无向图
                {
                    AdjacencyMat[EndIndex, StartIndex] = 1;
                    VertexList[StartIndex].InDegree++;
                    VertexList[StartIndex].OutDegree++;
                }
            }
        }

        /// <summary>
        /// 查询顶点的内部编号
        /// </summary>
        /// <param name="vertex">待查询的顶点</param>
        /// <returns>返回顶点的下标</returns>
        public int GetIndex(Vertex vertex)
        {
            int Index=-1;
            for (int i = 0; i < Size; i++)
            {
                if (VertexList[i].Name == vertex.Name)
                {
                    Index = i;
                    break;
                }
            }
            return Index;
        }

        /// <summary>
        /// 查询内部编号对应的顶点
        /// </summary>
        /// <param name="Index">待查询的内部编号</param>
        /// <returns>返回指定下标的顶点</returns>
        public Vertex GetVertex(int Index)
        {
            if (Index < Size)
            {
                return VertexList[Index];
            }
            else
            {
                throw new Exception("The index is bigger than the size!");
            }
        }


        /// <summary>
        /// 打印图的顶点数组
        /// </summary>
        public void PrintVertexList()
        {
            for (int i = 0; i < Size; i++)
            {
                Console.WriteLine("Name:{0}  No:{1}  InDegree:{2}  OutDegree:{3}", VertexList[i].Name, i,VertexList[i].InDegree,VertexList[i].OutDegree);
            }
        }

        /// <summary>
        /// 打印图的邻接矩阵
        /// </summary>
        public void PrintAdjacencyMat()
        {
            for (int j = 0; j < Size; j++)
            {
                for (int i = 0; i < Size; i++)
                {
                    Console.Write(AdjacencyMat[j, i]);
                    if (i != Size - 1)
                    {
                        Console.Write(" ");
                    }
                    else
                    {
                        Console.Write("\n");
                    }
                }
            }
        }
    }


    /// <summary>
    /// 以邻接表表示图
    /// </summary>
    class Graphic_List
    {
        public List<Vertex> Items;                    //邻接表
        bool IsDirection;

        /// <summary>
        /// Graphic_List构造函数
        /// </summary>
        /// <param name="Capacity">邻接表容量</param>
        public Graphic_List(int Capacity,bool DirectionBool)      //指定容量初始化
        {
            Items = new List<Vertex>(Capacity);
            IsDirection = DirectionBool;
        }

        /// <summary>
        /// 向图中添加顶点
        /// </summary>
        /// <param name="vertex">待添加的顶点</param>
        public void AddVertex(Vertex vertex)
        {
            if (GetIndex(vertex)==-1)    //确保该顶点不存在于临界表中
            {
                if (Items.Count < Items.Capacity)
                {
                    Items.Add(vertex);
                }
                else
                {
                    throw new Exception("the graphic is full");
                }
            }
        }

        /// <summary>
        /// 以顶点的方式向图中添加边
        /// </summary>
        /// <param name="StartVertex">待添加边的起点</param>
        /// <param name="EndVertex">待添加边的终点</param>
        public void AddEdge(Vertex StartVertex, Vertex EndVertex)
        {
            AddDirectedEdge(StartVertex, EndVertex);
            if (!IsDirection)
            {
                AddDirectedEdge(EndVertex, StartVertex);
            }

        }

        /// <summary>
        /// 以顶点的方式向图中添加有向边
        /// </summary>
        /// <param name="StartVertex">待添加边的起点</param>
        /// <param name="EndVertex">待添加的终点</param>
        public void AddDirectedEdge(Vertex StartVertex, Vertex EndVertex) //入度初度未修改
        {
            AddVertex(StartVertex);
            AddVertex(EndVertex);
            int StartIndex = GetIndex(StartVertex);
            int EndIndex = GetIndex(EndVertex);
            if (Items[StartIndex].NextVertex == null)    //后面无顶点,直接添加
            {
                Items[StartIndex].OutDegree++;
                Items[EndIndex].InDegree++;
                Items[StartIndex].NextVertex = EndVertex;
            }
            else    //否则查询链表最后一个顶点
            {
                Vertex TempVertex;
                bool IsAdd = false;
                TempVertex = Items[StartIndex].NextVertex;
                while (TempVertex.NextVertex != null)
                {
                    if (TempVertex.Name == EndVertex.Name)    //已经添加在链表中
                    {
                        IsAdd = true;
                        break;
                    }
                    else
                    {
                        TempVertex = TempVertex.NextVertex;
                    }
                }
                if (!IsAdd)
                {
                    Items[StartIndex].OutDegree++;
                    Items[EndIndex].InDegree++;
                    TempVertex.NextVertex = EndVertex;
                }
            }
        }

        /// <summary>
        /// 以内部编号方式向图中添加边
        /// </summary>
        /// <param name="StartIndex">待添加边的起点的内部编号</param>
        /// <param name="EndIndex">待添加的终点的内部编号</param>
        public void AddEdge(int StartIndex, int EndIndex)
        {
            if (StartIndex < Items.Count && EndIndex < Items.Count)    //确保顶点已经在图中
            {
                Vertex StartVertex, EndVertex;
                StartVertex = GetVertex(StartIndex);
                EndVertex = GetVertex(EndIndex);
            }
            else
            {
                throw new Exception("待添加的顶点不存在");
            }
        }

        /// <summary>
        /// 查询顶点的内部编号
        /// </summary>
        /// <param name="vertex">待查询的顶点</param>
        /// <returns>返回指定顶点的内部编号</returns>
        public int GetIndex(Vertex vertex)
        {
            int Index = -1;    //不存在则返回-1
            for (int i = 0; i < Items.Count; i++)
            {
                if (Items[i].Name == vertex.Name)
                {
                    Index = i;
                }
            }

            //或者采用该语句
            //
            //int a = Items.FindIndex(v => { if (v.Name == vertex.Name) return true; else return false; });
            return Index;
        }

        /// <summary>
        /// 查询内部编号对应的顶点
        /// </summary>
        /// <param name="Index">待查询的内部编号</param>
        /// <returns>返回指定顶点的内部编号</returns>
        public Vertex GetVertex(int Index)
        {
            return Items[Index];
        }

        /// <summary>
        /// 打印输出邻接表
        /// </summary>
        public void PrintGraphicList()
        {
            for (int i = 0; i < Items.Count; i++)
            {
                Vertex TempVertex = Items[i];
                while (TempVertex.NextVertex != null)
                {
                    Console.Write("{0}->", TempVertex.Name);
                    TempVertex = TempVertex.NextVertex;
                }
                Console.Write("{0}",TempVertex.Name);
                Console.Write("  In:{0}  Out:{1}\n", Items[i].InDegree, Items[i].OutDegree);
            }
        }
    }
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值