using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Maze
{
///
/// 图的顶点
///
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;
}
}
///
/// 邻接矩阵表示图
///
class Graphic_Matrix
{
private int Capacity; //图的容量
private bool IsDirection; //图是否有向标志
public Vertex[] VertexList; //图中顶点数组
public int[,] AdjacencyMat; //图的邻接矩阵
public int Size; //当前图中顶点数目
///
/// 邻接矩阵图的初始化
///
/// 图的最大容量
/// 有向标志
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;
}
}
}
///
/// 向图中添加顶点
///
/// 待添加的顶点
public void AddVertex(Vertex vertex)
{
if (GetIndex(vertex) == -1) //确保该顶点未添加
{
if (Size < Capacity)
{
VertexList[Size++] = vertex;
}
else //超容量
{
throw new Exception("The graphic is full!");
}
}
}
///
/// 以顶点的方式添加边
///
/// 边的起点
/// 边的终点
public void AddEdge(Vertex StartVertex, Vertex EndVertex)
{
int Index1, Index2;
AddVertex(StartVertex); //添加该顶点,若图中已有该顶点,则会直接返回
Index1 = GetIndex(StartVertex);
AddVertex(EndVertex);
Index2 = GetIndex(EndVertex);
AddEdge(Index1, Index2);
}
///
/// 以内部编号添加顶点
///
/// 起点的内部编号
/// 终点的内部编号
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++;
}
}
}
///
/// 查询顶点的内部编号
///
/// 待查询的顶点
/// 返回顶点的下标
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;
}
///
/// 查询内部编号对应的顶点
///
/// 待查询的内部编号
/// 返回指定下标的顶点
public Vertex GetVertex(int Index)
{
if (Index < Size)
{
return VertexList[Index];
}
else
{
throw new Exception("The index is bigger than the size!");
}
}
///
/// 打印图的顶点数组
///
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);
}
}
///
/// 打印图的邻接矩阵
///
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");
}
}
}
}
}
///
/// 以邻接表表示图
///
class Graphic_List
{
public List Items; //邻接表
bool IsDirection;
///
/// Graphic_List构造函数
///
/// 邻接表容量
public Graphic_List(int Capacity,bool DirectionBool) //指定容量初始化
{
Items = new List(Capacity);
IsDirection = DirectionBool;
}
///
/// 向图中添加顶点
///
/// 待添加的顶点
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");
}
}
}
///
/// 以顶点的方式向图中添加边
///
/// 待添加边的起点
/// 待添加边的终点
public void AddEdge(Vertex StartVertex, Vertex EndVertex)
{
AddDirectedEdge(StartVertex, EndVertex);
if (!IsDirection)
{
AddDirectedEdge(EndVertex, StartVertex);
}
}
///
/// 以顶点的方式向图中添加有向边
///
/// 待添加边的起点
/// 待添加的终点
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;
}
}
}
///
/// 以内部编号方式向图中添加边
///
/// 待添加边的起点的内部编号
/// 待添加的终点的内部编号
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("待添加的顶点不存在");
}
}
///
/// 查询顶点的内部编号
///
/// 待查询的顶点
/// 返回指定顶点的内部编号
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;
}
///
/// 查询内部编号对应的顶点
///
/// 待查询的内部编号
/// 返回指定顶点的内部编号
public Vertex GetVertex(int Index)
{
return Items[Index];
}
///
/// 打印输出邻接表
///
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);
}
}
}
}