转自:https://blog.csdn.net/u011131296/article/details/12779181

简介

图表示点之间的关系,在C#中通过节点对象的集合来表示点(Vertex),用邻接矩阵(adjacency matrix)来表示点之间的关系。下面来看C#实现。

PS:本片文章是我复习的笔记,代码注释很全。勿吐槽。

表示点的对象

下面实现代码:

    class Vertex{public string Data;public bool IsVisited;public Vertex(string Vertexdata){Data = Vertexdata;}}

每个节点包含两个字段,分别为节点数据以及表示是否被访问过的一个布尔类型。

表示图的对象

图中除了需要点的集合和邻接矩阵之外,还需要一些基本的向图中添加或删除元素的方法,以及一个构造方法来对图进行初始化。

 public class Graph{//图中所能包含的点上限private const int Number = 10;//顶点数组private Vertex[] vertiexes;//邻接矩阵public int[,] adjmatrix;//统计当前图中有几个点int numVerts = 0;//初始化图public Graph(){//初始化邻接矩阵和顶点数组adjmatrix = new Int32[Number, Number];vertiexes = new Vertex[Number];//将代表邻接矩阵的表全初始化为0for (int i = 0; i < Number; i++){for (int j = 0; j < Number; j++){adjmatrix[i, j] = 0;}}}//向图中添加节点public void AddVertex(String v){vertiexes[numVerts] = new Vertex(v);numVerts++;}//向图中添加有向边public void AddEdge(int vertex1, int vertex2){adjmatrix[vertex1, vertex2] = 1;//adjmatrix[vertex2, vertex1] = 1;}//显示点public void DisplayVert(int vertexPosition){Console.WriteLine(vertiexes[vertexPosition]+" ");}
}

拓扑排序(TopSort)

拓扑排序是对一个有向的,并且不是环路的图中所有的顶点线性化。需要如下几个步骤

1.首先找到没有后继的节点。

2.将这个节点加入线性栈中

3.在图中删除这个节点

4.重复步骤1,2,3

因此,首先需要找到后继节点的方法:

        //寻找图中没有后继节点的点//具体表现为邻接矩阵中某一列全为0//此时返回行号,如果找不到返回-1private int FindNoSuccessor(){bool isEdge;//循环行for (int i = 0; i < numVerts; i++){isEdge = false;//循环列,有一个1就跳出循环for (int j = 0; j < numVerts; j++){if (adjmatrix[i, j] == 1){isEdge = true;break;}}if (!isEdge){return i;}}return -1;}

此外还需要删除图中点的方法,这个方法不仅需要删除图中对应位置的点,还需要删除邻接矩阵对应的行和列,因此设置了两个辅助方法,见代码。

//删除图中的点//需要两个操作,分别从数组中删除点//从邻接矩阵中消去被删点的行和列private void DelVertex(int vert){//保证不越界if (vert <= numVerts - 1){//删除节点for (int i = vert; i < numVerts; i++){vertiexes[i] = vertiexes[i + 1];}//删除邻接矩阵的行for (int j = vert; j < numVerts; j++){MoveRow(j, numVerts);}//删除邻接矩阵中的列,因为已经删了行,所以少一列for (int k = vert; k < numVerts - 1;k++ ){MoveCol(k, numVerts-1);}//删除后减少一个numVerts--;}}//辅助方法,移动邻接矩阵中的行private void MoveRow(int row, int length){for (int col = row; col < numVerts; col++){adjmatrix[row, col] = adjmatrix[row + 1, col];}}//辅助方法,移动邻接矩阵中的列private void MoveCol(int col, int length){for (int row = col; row < numVerts; row++){adjmatrix[row, col] = adjmatrix[row, col+1];}}

有了这几个方法,就可以按照步骤开始拓扑排序了:

       //拓扑排序//找到没有后继节点的节点,删除,加入一个栈,然后输出public void TopSort(){int origVerts = numVerts;//存放返回节点的栈System.Collections.Stack result = new Stack();while (numVerts > 0){//找到第一个没有后继节点的节点int currVertex = FindNoSuccessor();if (currVertex == -1){Console.WriteLine("图为环路图,不能搞拓扑排序");return;}//如果找到,将其加入返回结果栈result.Push(vertiexes[currVertex].Data);//然后删除此节点DelVertex(currVertex);}/*输出排序后的结果*/Console.Write("拓扑排序的顺序为:");while (result.Count > 0){Console.Write(result.Pop()+" ");}/*输出排序后的结果*/}

下面,对拓扑排序进行测试,代码如下:

 static void Main(string[] args){Graph g = new Graph();g.AddVertex("A");g.AddVertex("B");g.AddVertex("C");g.AddVertex("D");g.AddEdge(0, 1);g.AddEdge(1, 2);g.AddEdge(2, 3);g.AddEdge(3, 4);g.TopSort();Console.ReadKey();}

测试结果:

图的遍历

很多时候,我们需要知道从图中给定点到另一个点是否能走通,比如几个车站之间是否可以连接。这时我们需要对图进行查找,查找大概可以分为两类,深度优先遍历和广度优先遍历,下面先来看深度优先遍历。

深度优先遍历(Depth-First Search)

深度优先遍历首先从一个点开始,到一条路径结束,然后循环找第二条路径,到结束,依此往复。

首先我们需要一个辅助方法返回给定的点最近一个连接并且未被访问过的序号。

        //从邻接矩阵查找给定点第一个相邻且未被访问过的点//参数v是给定点在邻接矩阵的行private int GetAdjUnvisitedVertex(int v){for (int j = 0; j < numVerts; j++){if (adjmatrix[v,j]==1 && vertiexes[j].IsVisited == false){return j;}}return -1;}

下面,就可以进行深度优先遍历了:

//深度优先遍历public void DepthFirstSearch(){//声明一个存储临时结果的栈System.Collections.Stack s = new Stack();//先访问第一个节点vertiexes[0].IsVisited = true;DisplayVert(0);s.Push(0);int v;while (s.Count > 0){//获得和当前节点连接的未访问过节点的序号v = GetAdjUnvisitedVertex((int)s.Peek());if (v == -1){s.Pop();}else{//标记为已经被访问过vertiexes[v].IsVisited = true;DisplayVert(v);s.Push(v);}}//重置所有节点为未访问过for (int u = 0; u < numVerts; u++){vertiexes[u].IsVisited = false;}}

广度优先遍历(Breadth-First Search)

广度优先遍历首先遍历层级。算法如下:

//广度优先遍历public void BreadthFirstSearch(){System.Collections.Queue q = new Queue();/*首先访问第一个节点*/vertiexes[0].IsVisited = true;DisplayVert(0);q.Enqueue(0);/*第一个节点访问结束*/int vert1, vert2;while (q.Count > 0){/*首先访问同层级第一个节点*/vert1 = (int)q.Dequeue();vert2 = GetAdjUnvisitedVertex(vert1);/*结束*/while (vert2 != -1){/*首先访问第二个节点*/vertiexes[vert2].IsVisited = true;DisplayVert(vert2);q.Enqueue(vert2);//寻找邻接的vert2 = GetAdjUnvisitedVertex(vert1);}}//重置所有节点为未访问过for (int u = 0; u < numVerts; u++){vertiexes[u].IsVisited = false;}}

下面我们来测试深度优先和广度优先遍历:

我们的测试生成一个如下的图:

测试代码:

static void Main(string[] args){Graph g = new Graph();g.AddVertex("A");g.AddVertex("B");g.AddVertex("C");g.AddVertex("D");g.AddVertex("E");g.AddVertex("F");g.AddVertex("G");g.AddEdge(0, 1);g.AddEdge(0, 2);g.AddEdge(1, 3);g.AddEdge(2, 4);g.AddEdge(3, 5);g.AddEdge(4, 6);Console.WriteLine("\n深度优先遍历");g.DepthFirstSearch();Console.WriteLine("\n广度优先遍历");g.BreadthFirstSearch();Console.ReadKey();}

运行结果:

C#实现图(Graph)相关推荐

  1. 从图(Graph)到图卷积(Graph Convolution):漫谈图 神经⽹络模型 (⼀)

    点击上方"小白学视觉",选择加"星标"或"置顶" 重磅干货,第一时间送达 作者最近看了一些图与图卷积神经网络的论文,深感其强大,但一些Sur ...

  2. 数据结构--图(Graph)详解(四)

    数据结构–图(Graph)详解(四) 文章目录 数据结构--图(Graph)详解(四) 一.图中几个NB的算法 1.普里姆算法(Prim算法)求最小生成树 2.克鲁斯卡尔算法(Kruskal算法)求最 ...

  3. 数据结构--图(Graph)详解(三)

    数据结构–图(Graph)详解(三) 文章目录 数据结构--图(Graph)详解(三) 一.深度优先生成树和广度优先生成树 1.铺垫 2.非连通图的生成森林 3.深度优先生成森林 4.广度优先生成森林 ...

  4. 数据结构--图(Graph)详解(二)

    数据结构–图(Graph)详解(二) 文章目录 数据结构--图(Graph)详解(二) 一.图的存储结构 1.图的顺序存储法 2.图的邻接表存储法 3.图的十字链表存储法 4.图的邻接多重表存储法 二 ...

  5. 数据结构--图(Graph)详解(一)

    数据结构–图(Graph)详解(一) 文章目录 数据结构--图(Graph)详解(一) 一.图的基本概念 1.图的分类 2.弧头和弧尾 3.入度和出度 4.(V1,V2) 和 < V1,V2 & ...

  6. python加载模型文件进行图片分类_tensorflow通过模型文件,使用tensorboard查看其模型图Graph方式...

    Google提供了一个工具,TensorBoard,它能以图表的方式分析你在训练过程中汇总的各种数据,其中包括Graph结构. 所以我们可以简单的写几行Pyhton,加载Graph,只在logdir里 ...

  7. 从图(Graph)到图卷积(Graph Convolution):漫谈图神经网络 (二)

    在从图(Graph)到图卷积(Graph Convolution): 漫谈图神经网络 (一)中,我们简单介绍了基于循环图神经网络的两种重要模型,在本篇中,我们将着大量笔墨介绍图卷积神经网络中的卷积操作 ...

  8. 从图(Graph)到图卷积(Graph Convolution):漫谈图神经网络模型 (一)

    本文属于图神经网络的系列文章,文章目录如下: 从图(Graph)到图卷积(Graph Convolution):漫谈图神经网络模型 (一) 从图(Graph)到图卷积(Graph Convolutio ...

  9. 数据结构与算法(python):图(Graph)的基本概念及应用

    参考自 MOOC数据结构与算法Python版 本章代码: https://github.com/HuiFang-hub/-/tree/main. 目录 一.图Graph的概念 1.1 互联网 1.2 ...

  10. 从图(Graph)到图卷积(Graph Convolution):漫谈图神经网络模型 (二)

    本文属于图神经网络的系列文章,文章目录如下: 从图(Graph)到图卷积(Graph Convolution):漫谈图神经网络模型 (一) 从图(Graph)到图卷积(Graph Convolutio ...

最新文章

  1. 防抖 节流_面试必备考点:防抖与节流
  2. 源码分析shiro认证授权流程
  3. mysql 导入CSV数据 [转]
  4. linux 中 timeval结构体
  5. npm install 卡住的时候的处理
  6. 在超链接href中实现form的提交
  7. PHP Opcache(ZendOptimizerPlus)的安装配置详解
  8. java连接oracle sid_jdbc连接数据库使用sid和service_name的区别
  9. Luogu1373 小a和uim之大逃离
  10. Delphi2007中安装OCX控件
  11. 基于微信小程序的记账系统
  12. 【时间序列分析】01. 时间序列·平稳序列
  13. 基于hilbert变换的数字信号_hilbert变换
  14. 二元回归方程matlab,matlab 多元非线性回归方程问题
  15. JS清除IE浏览器缓存的方法
  16. java map.put map_java中map的put方法
  17. 清默网络——负载均衡
  18. Bootstrap.yml 和 application.yml
  19. windows系统下载合集
  20. 爱普生连续供墨系统故障排除方法

热门文章

  1. 计算机图形学E3——OpenGL 中点画圆
  2. et al、e.g.、i.e.读音及释义
  3. python调用另一个.py文件中的类和函数
  4. CSDN Markdown编辑器帮助文档
  5. ubuntu jdk tomcat mysql_Ubuntu下JDK+Tomcat+MySql环境的搭建
  6. 启动子级时出错_WHO I级脑膜瘤手术或放射外科治疗后的恶性转变
  7. pyqt5 判断lineedit是否为空_是否注意过 isEmpty 和 isBlank 区别?
  8. java8 hadoop_java8-模拟hadoop
  9. bmaplib vue 调用_Vue集成百度地图
  10. mysql 自定义函数 找不到表_mysql 自定义函数