重新整理数据结构与算法(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支持诸多存储引擎,而各种存储引 ...
随机推荐
- s3cmd的使用
目录 1. 安装s3cmd 2. 配置s3cmd 3. 使用s3cmd [前言] s3cmd 是用于创建S3桶,上传,检索和管理数据到对象存储命令行实用程序. 本文将指导linux下安装s3cmd程序 ...
- C语言:数的保存 原码 反码 补码
a=6 a=-18 a 的原码就是0000 0000 0000 0110 1000 0000 0001 0010 ...
- python 爬取网络小说 清洗 并下载至txt文件
什么是爬虫 网络爬虫,也叫网络蜘蛛(spider),是一种用来自动浏览万维网的网络机器人.其目的一般为编纂网络索引. 网络搜索引擎等站点通过爬虫软件更新自身的网站内容或其对其他网站的索引.网络爬虫可以 ...
- Eclipse配置反编译插件jadclipse
参考自:https://blog.csdn.net/moneyshi/article/details/79715891 Jad是一个Java的一个反编译工具,是用命令行执行,和通常JDK自带的java ...
- org.apache.maven.archiver.mavenarchiver.getmanifest怎么解决——原因就是你的maven的配置文件不是最新的
转载:https://www.cnblogs.com/flytop/p/8933728.html原因就是你的maven的配置文件不是最新的 1.help ->Install New Softwa ...
- Python+Requests+Xpath实现动态参数获取实战
1.古诗文网直接登录时,用浏览器F12抓取登录接口的入参,我们可以看到框起来的key对应的value是动态参数生成的,需获取到: 2.登录接口入参的值一般是登录接口返回的原数据值,若刷新后接口与对应源 ...
- JavaScript实现拖放效果
JavaScript实现拖放效果 笔者实现该效果也是套用别人的轮子的.传送门 然后厚颜无耻的贴别人的readme~,笔者为了方便查阅就直接贴了,有不想移步的可以看这篇.不过还是最好请到原作者的GitH ...
- ML-支持向量机(SVM)
简介 支持向量机是一种二分类模型,寻找一个超平面来对样本进行分割,分割的原则是保证间隔最大化. 如果一个线性函数能够将样本分开,称这些数据样本是线性可分的. 在二维空间线性函数就是一条直线,在三维空间 ...
- 一次搞懂JavaScript对象
索引 目录 索引 1. 对象与类 2.对象使用 2.1 语法 2.2 属性 3.对象特性 4.对象的创建 4.1 字面量 4.2 工厂函数 4.3 构造函数 4.4 class类 4.5 对象与单例模 ...
- 记一次Hvv中遇到的API接口泄露而引起的一系列漏洞
引言 最近朋友跟我一起把之前废弃的公众号做起来了,更名为鹿鸣安全团队,后面陆续会更新个人笔记,有趣的渗透经历,内网渗透相关话题等,欢迎大家关注 前言 Hvv中的一个很有趣的漏洞挖掘过程,从一个简单的A ...