重新整理数据结构与算法(c#)—— 图的深度遍历和广度遍历[十一]
参考网址:https://www.cnblogs.com/aoximin/p/13162635.html
前言
简介图:
在数据的逻辑结构D=(KR)中,如果K中结点对于关系R的前趋和后继的个数不加限制,即仅含一种任意的关系,则称这种数据结构为图形结构。
来源百度百科
图形结构是一种比树形结构更复杂的非线性结构。在树形结构中,结点间具有分支层次关系,每一层上的结点只能和上一层中的至多一个结点相关,但可能和下一层的多个结点相关。而在图形结构中,任意两个结点之间都可能相关,即结点之间的邻接关系可以是任意的
然后就是盗图阶段:
后面就是一些基础常识,我找到一个比较全的:
https://www.cnblogs.com/songgj/p/9107797.html
正文
那么就来看一下图的深度遍历和广度遍历吧。
先来定义一个图:
public class Graph
{
private List<String> vertexList; //存储顶点集合
private int[,] edges; //存储图对应的邻结矩阵
private Boolean[] isVisited;// 判断是否访问了
int numOfEdges;
public Graph(int n){
vertexList = new List<string>();
edges = new int[8, 8];
isVisited = new Boolean[8];
}
/// <summary>
/// 增加节点
/// </summary>
/// <param name="vertex">节点</param>
public void addVertex(string vertex)
{
vertexList.Add(vertex);
}
public void insertEdge(int x,int y,int weight)
{
//增加他们的连线 且设置他们的权重
edges[x, y] = 1;
edges[y, x] = 1;
numOfEdges++;
}
public void showEdges()
{
for (int i=0;i< isVisited.Length;i++)
{
for (int j = 0; j < isVisited.Length; j++)
{
Console.Write(edges[i,j]+" ");
}
Console.WriteLine();
}
}
}
测试一下:
String[] Vertexs = { "1", "2", "3", "4", "5", "6", "7", "8" };
//创建图对象
Graph graph = new Graph(Vertexs.Count());
//循环的添加顶点
foreach (String vertex in Vertexs)
{
graph.addVertex(vertex);
}
//更新边的关系
graph.insertEdge(0, 1, 1);
graph.insertEdge(0, 2, 1);
graph.insertEdge(1, 3, 1);
graph.insertEdge(1, 4, 1);
graph.insertEdge(3, 7, 1);
graph.insertEdge(4, 7, 1);
graph.insertEdge(2, 5, 1);
graph.insertEdge(2, 6, 1);
graph.insertEdge(5, 6, 1);
graph.showEdges();
Console.ReadKey();
结果:
这么看可能不清晰哈,那么我画个图,看一下。
这是下面这张图哈:
深度遍历:
private int getFirstNeighbor(int index)
{
for (int j = 0; j < isVisited.Length; j++)
{
if (edges[index, j] > 0)
{
return j;
}
}
return -1;
}
/// <summary>
/// 通过邻接节点来获取下一个节点
/// </summary>
/// <param name="v1"></param>
/// <param name="v2"></param>
/// <returns></returns>
public int getNextNeighbor(int v1, int v2)
{
for (int j = v2+1; j < isVisited.Length; j++)
{
if (edges[v1, j] > 0)
{
return j;
}
}
return -1;
}
/// <summary>
/// 深度遍历
/// </summary>
/// <param name="i"></param>
public void dfs(int i)
{
//打印遍历的值
Console.Write(vertexList[i]+" ");
isVisited[i] = true;
int w = getFirstNeighbor(i);
while (w != -1)
{
if (!isVisited[w])
{
dfs(w);
}
w = getNextNeighbor(i,w);
}
}
然后调用函数:
graph.dfs(0);
得到的结果是:
看下广度遍历吧:
//对一个结点进行广度优先遍历的方法
public void bfs(int i)
{
//打印遍历的值
Console.Write(vertexList[i] + " ");
LinkedList<int> queue = new LinkedList<int>();
queue.AddLast(i);
int u;
while (queue.Count != 0)
{
u = queue.First.Value;
queue.RemoveFirst();
int w = getFirstNeighbor(i);
while (w != -1)
{
if (!isVisited[w])
{
Console.Write(vertexList[w] + " ");
isVisited[w] = true;
queue.AddLast(w);
}
w = getNextNeighbor(u, w);
}
}
}
然后调用:
Console.WriteLine("广度遍历");
graph.bfs(0);
结果:
//自己编写的代码 仅供参考
public class Node<T>
{
public bool accessed = false;
public T t;
}
public class MyGrapic<T>
{
private Node<T>[] arryNode = null;
private int[,] Matrix = null;
private int num;
public MyGrapic(Node<T>[] arrn)
{
arryNode = arrn;
var n = arrn.Length;
Matrix = new int[n, n];
this.num = n;
this.initMatix();
}
private void initMatix()
{
for (int i = 0; i < this.num; i++)
{
for (int j = 0; i < this.num; i++)
{
Matrix[i, j] = 0;
}
}
}
public void SetEdget(Node<T> n1, Node<T> n2)
{
int index1 = findNode(n1);
int index2 = findNode(n2);
Matrix[index1, index2] = 1;
Matrix[index2, index1] = 1;
}
private int findNode(Node<T> n)
{
int index = -1;
for (int i = 0; i < this.num; i++)
{
var a = arryNode[i]; index++;
if (a.Equals(n))
{
return i;
}
}
return index;
}
public void PrintMatix()
{
for (int i = 0; i < this.num; i++)
{
for (int j = 0; j < this.num; j++)
{
Console.Write("{0} ", Matrix[i, j]);
}
Console.WriteLine();
}
}
private Node<T> findNeighbor(Node<T> node)
{
int index1 = findNode(node);
int index2 = -1;
for (int i = 0; i < this.num; i++)
{
if (Matrix[index1, i] == 1)
{
if (arryNode[i].accessed == false)
{
index2 = i;
break;
}
}
}
if (index2 == -1)
{
return null;
}
return arryNode[index2];
}
/// <summary>
/// 通过邻接节点来获取下一个节点
/// </summary>
/// <param name="node1"></param>
/// <param name="node2"></param>
/// <returns></returns>
private Node<T> findNeighbor2(Node<T> node1, Node<T> node2)
{
int index1 = findNode(node1);
int j = findNode(node2);
int index2 = -1;
for (int i = j; i < this.num; i++)
{
if (Matrix[index1, i] == 1)
{
if (arryNode[i].accessed == false)
{
index2 = i;
break;
}
}
}
if (index2 == -1)
{
return null;
}
return arryNode[index2];
}
public void DSF(Node<T> node)
{
if (node.accessed == true)
{
return;
}
Console.Write("{0}\t", node.t);
node.accessed = true;
var neighbor = findNeighbor(node);
while (neighbor != null)
{
DSF(neighbor);
neighbor = findNeighbor2(node, neighbor);
}
}
}
重新整理数据结构与算法(c#)—— 图的深度遍历和广度遍历[十一]的更多相关文章
- Python数据结构与算法之图的最短路径(Dijkstra算法)完整实例
本文实例讲述了Python数据结构与算法之图的最短路径(Dijkstra算法).分享给大家供大家参考,具体如下: # coding:utf-8 # Dijkstra算法--通过边实现松弛 # 指定一个 ...
- Python数据结构与算法之图的广度优先与深度优先搜索算法示例
本文实例讲述了Python数据结构与算法之图的广度优先与深度优先搜索算法.分享给大家供大家参考,具体如下: 根据维基百科的伪代码实现: 广度优先BFS: 使用队列,集合 标记初始结点已被发现,放入队列 ...
- 图的存储及遍历 深度遍历和广度遍历 C++代码实现
/*图的存储及遍历*/ #include<iostream> using namespace std; //----------------------------------- //邻接 ...
- 5, java数据结构和算法: 栈 , 入栈, 出栈, 正序遍历,,逆序遍历
直接上代码: class ArrayStack{ //用数组模拟栈 int maxSize; int[] stack; int top = -1;//表示栈顶 public ArrayStack(in ...
- 4,java数据结构和算法:双向链表 ,有序添加,正向遍历,反向遍历, 增删改查
直接上代码 //节点 class HeroNodeD{ int no; String name; String nickName; HeroNodeD pre;//前一节点 HeroNodeD nex ...
- 数据结构学习-BST二叉查找树 : 插入、删除、中序遍历、前序遍历、后序遍历、广度遍历、绘图
二叉查找树(Binary Search Tree) 是一种树形的存储数据的结构 如图所示,它具有的特点是: 1.具有一个根节点 2.每个节点可能有0.1.2个分支 3.对于某个节点,他的左分支小于自身 ...
- Leetcode 课程表 C++ 图的深度搜索和广度搜索练习
广度搜索(degree) struct GraphNode{ int label; vector<GraphNode*> neighbours; GraphNode(int x):labe ...
- The Game Of Life – 数据结构与算法的敲门砖
The Game Of Life(生命游戏,又称为细胞自动机)几乎是所有数据结构与算法导论教程前言的一个很经典的程序了.这是一个零玩家游戏,发生在一个平面网格里.每个格子的细胞都有死亡和存活两种状态, ...
- MySQL 索引背后的数据结构及算法原理
本文转载自http://blog.jobbole.com/24006/ 摘要本文以MySQL数据库为研究对象,讨论与数据库索引相关的一些话题.特别需要说明的是,MySQL支持诸多存储引擎,而各种存储引 ...
随机推荐
- python 10篇 操作mysql
一.操作数据库 使用pip install pymysql,安装pymysql模块,使用此模块连接MySQL数据库并操作数据库. import pymysql host = 'ip地址' # 链接的主 ...
- 小刻也能看懂的Unraid系统使用手册:基础篇
小刻也能看懂的Unraid系统使用手册 基础篇 Unraid系统简介 Unraid 的本体其实是 Linux,它主要安装在 NAS 和 All in One 服务器上,经常可以在 Linus 的视频里 ...
- iframe跨域访问出现的cookie问题,提供两种解决方案
最近在java项目对接时出现的一个问题.A系统嵌入B系统页面时,使用iframe去嵌入B系统页面丢失sessionid,导致B系统认为是未进行登录的请求,从而跳转到了B系统登录页. 解决方法查看此博客 ...
- Tutorial_6 运行结果
1.buyer_favorites.txt 2.代码 package mapreduce; import java.io.IOException; import java.util.Iterator; ...
- static能修饰什么
简洁易懂讲清原理,讲不清你来打我~ 修饰普通变量,修改变量的存储区域和生命周期,使变量存储在静态区,在main函数运行前就分配空间,有初始值就初始值,没有初始值就系统默认值初始化 修饰普通函数,修改函 ...
- Docker安装和常用配置【Linux】
Linux下安装配置docker 安装指南:https://developer.aliyun.com/article/110806 一.配置国内镜像源 1.1 设置国内阿里巴巴下载源 [root@lo ...
- 一定要收藏的5个优秀的SpringCloud开源项目
上一期为大家推荐了几个前端模板,没看过的点下面 一定要收藏的5个后台管理系统的前端框架 今天再为大家推荐几个优秀的SpringCloud开源脚手架项目,开箱即用,不管是学习还是开发新项目,都非常不错. ...
- [SHOI2014]概率充电器 题解
注意到本题的贡献是不带权的,所以期望其实就是每个点的概率之和. 本题正着做好像不是很好做,要考虑 \(P(A+B)=P(A)+P(B)-P(A)P(B)\) 的容斥(因为这是两个条件至少满足一个,所以 ...
- Mysql数据量较大时分页查询优化
据表 collect ( id, title ,info ,vtype) 就这4个字段,其中 title 用定长,info 用text, id 是主键,vtype是int,vtype是索引. 最后co ...
- 警告: Runner org.junit.internal.runners.ErrorReportingRunner (used on class cn.star.MybatisTest)
bug描述: 在Springboot整合Junit的时候编写测试类进行测试时, 出现以下错误: 十一月 28, 2019 2:53:48 下午 org.junit.vintage.engine.des ...