图的遍历之DSF深度优先算法6.2.1(网络整理)
图的遍历之深度优先算法伪代码描述(和树的前序遍历相似,实际上树可以看成特殊的图:N个顶点有N-1条边,不曾在回路!即树是图连通中最少边的情况)
图片来自网络
如上图:
深度优先遍历:
先选取一个顶点访问它,然后深度优先遍历它的每个未访问的邻接点
#include<stdlib.h>
#include<stdbool.h>
#include<stdio.h>
#define MaxVertexNum 100 /* 最大顶点数设为100 */
typedef int Vertex; /* 用顶点下标表示顶点,为整型 */
typedef int WeightType; /* 边的权值设为整型 */
typedef char DataType; /* 顶点存储的数据类型设为字符型 */ bool Visited[MaxVertexNum];/* 边的定义 */
typedef struct ENode *PtrToENode;
struct ENode{ Vertex V1, V2; /* 有向边<V1, V2> */ WeightType Weight; /* 权重 */
};
typedef PtrToENode Edge; /* 邻接点的定义 */
typedef struct AdjVNode *PtrToAdjVNode;
struct AdjVNode{ Vertex AdjV; /* 邻接点下标 */ WeightType Weight; /* 边权重 */ PtrToAdjVNode Next; /* 指向下一个邻接点的指针 */
}; /* 顶点表头结点的定义 */
typedef struct Vnode{ PtrToAdjVNode FirstEdge;/* 边表头指针 */ DataType Data; /* 存顶点的数据 */ /* 注意:很多情况下,顶点无数据,此时Data可以不用出现 */
} AdjList[MaxVertexNum]; /* AdjList是邻接表类型 */ /* 图结点的定义 */
typedef struct GNode *PtrToGNode;
struct GNode{ int Nv; /* 顶点数 */ int Ne; /* 边数 */ AdjList G; /* 邻接表 */
};
typedef PtrToGNode LGraph; /* 以邻接表方式存储的图类型 */ LGraph CreateGraph( int VertexNum )
{ Vertex V;
/* 初始化一个有VertexNum个顶点但没有边的图 */
LGraph Graph=(LGraph)malloc(sizeof(struct GNode));
Graph->Nv=VertexNum;
Graph->Ne=0;/* 初始化邻接表头指针 */ /* 注意:这里默认顶点编号从0开始,到(Graph->Nv - 1) */ for (V=0; V<Graph->Nv; V++) Graph->G[V].FirstEdge = NULL; return Graph;
} void InsertEdge( LGraph Graph, Edge E ) {PtrToAdjVNode NewNode; /* 插入边 <V1, V2> */ /* 为V2建立新的邻接点 */ NewNode = (PtrToAdjVNode)malloc(sizeof(struct AdjVNode)); NewNode->AdjV = E->V2; NewNode->Weight = E->Weight; /* 将V2插入V1的表头 */ NewNode->Next = Graph->G[E->V1].FirstEdge; Graph->G[E->V1].FirstEdge = NewNode; /* 若是无向图,还要插入边 <V2, V1> */ /* 为V1建立新的邻接点 */ NewNode = (PtrToAdjVNode)malloc(sizeof(struct AdjVNode)); NewNode->AdjV = E->V1; NewNode->Weight = E->Weight; /* 将V1插入V2的表头 */ NewNode->Next = Graph->G[E->V2].FirstEdge; Graph->G[E->V2].FirstEdge = NewNode; }LGraph BuildGraph() { LGraph Graph; Edge E; Vertex V; int Nv, i; scanf("%d", &Nv); /* 读入顶点个数 */ Graph = CreateGraph(Nv); /* 初始化有Nv个顶点但没有边的图 */ scanf("%d", &(Graph->Ne)); /* 读入边数 */ if ( Graph->Ne != 0 ) { /* 如果有边 */ E = (Edge)malloc( sizeof(struct ENode) ); /* 建立边结点 */ /* 读入边,格式为"起点 终点 权重",插入邻接矩阵 */ for (i=0; i<Graph->Ne; i++) { scanf("%d %d %d", &E->V1, &E->V2, &E->Weight); /* 注意:如果权重不是整型,Weight的读入格式要改 */ InsertEdge( Graph, E ); } free(E);} /* 如果顶点有数据的话,读入数据 */ for (V=0; V<Graph->Nv; V++) scanf(" %c", &(Graph->G[V].Data)); return Graph; } /* 邻接表存储的图 - DFS */void Visit( Vertex V ){printf("正在访问顶点%d\n", V);}/* Visited[]为全局变量,已经初始化为false */void DFS( LGraph Graph, Vertex V, void (*PVisit)(Vertex) ){ /* 以V为出发点对邻接表存储的图Graph进行DFS搜索 */PtrToAdjVNode W;(*PVisit)( V ); /* 访问第V个顶点 */Visited[V] = true; /* 标记V已访问 */for( W=Graph->G[V].FirstEdge; W; W=W->Next ) /* 对V的每个邻接点W->AdjV */if ( !Visited[W->AdjV] ) /* 若W->AdjV未被访问 */DFS( Graph, W->AdjV, PVisit ); /* 则递归访问之 */}int main(){for(int i=0;i<MaxVertexNum;i++)Visited[i]=false;//初始化为falseLGraph Graph=BuildGraph();DFS(Graph,0,Visit);return 0;}
#include<stdlib.h>
#include<stdbool.h>
#include<stdio.h>
#define MaxVertexNum 100 /* 最大顶点数设为100 */
#define INFINITY 65535 /* ∞设为双字节无符号整数的最大值65535*/
typedef int Vertex; /* 用顶点下标表示顶点,为整型 */
typedef int WeightType; /* 边的权值设为整型 */
typedef char DataType; /* 顶点存储的数据类型设为字符型 */
bool Visited[MaxVertexNum];
/* 边的定义 */
typedef struct ENode *PtrToENode;
struct ENode{ Vertex V1, V2; /* 有向边<V1, V2> */ WeightType Weight; /* 权重 */
};
typedef PtrToENode Edge; /* 图结点的定义 */
typedef struct GNode *PtrToGNode;
struct GNode{ int Nv; /* 顶点数 */ int Ne; /* 边数 */ WeightType G[MaxVertexNum][MaxVertexNum]; /* 邻接矩阵 */ DataType Data[MaxVertexNum]; /* 存顶点的数据 */ /* 注意:很多情况下,顶点无数据,此时Data[]可以不用出现 */
};
typedef PtrToGNode MGraph; /* 以邻接矩阵存储的图类型 */ MGraph CreateGraph( int VertexNum )
{ /* 初始化一个有VertexNum个顶点但没有边的图 */ Vertex V, W; MGraph Graph; Graph = (MGraph)malloc(sizeof(struct GNode)); /* 建立图 */ Graph->Nv = VertexNum; Graph->Ne = 0; /* 初始化邻接矩阵 */ /* 注意:这里默认顶点编号从0开始,到(Graph->Nv - 1) */ for (V=0; V<Graph->Nv; V++) for (W=0; W<Graph->Nv; W++) if(V==W) Graph->G[V][W]=0;else Graph->G[V][W] = INFINITY; return Graph;
} void InsertEdge( MGraph Graph, Edge E ) {/* 插入边 <V1, V2> */ Graph->G[E->V1][E->V2] = E->Weight; /* 若是无向图,还要插入边<V2, V1> */ Graph->G[E->V2][E->V1] = E->Weight; }MGraph BuildGraph() { MGraph Graph; Edge E; Vertex V; int Nv, i; scanf("%d", &Nv); /* 读入顶点个数 */ Graph = CreateGraph(Nv); /* 初始化有Nv个顶点但没有边的图 */ scanf("%d", &(Graph->Ne)); /* 读入边数 */ if ( Graph->Ne != 0 ) { /* 如果有边 */ E = (Edge)malloc(sizeof(struct ENode)); /* 建立边结点 */ /* 读入边,格式为"起点 终点 权重",插入邻接矩阵 */ for (i=0; i<Graph->Ne; i++) { scanf("%d %d %d", &E->V1, &E->V2, &E->Weight); /* 注意:如果权重不是整型,Weight的读入格式要改 */ InsertEdge( Graph, E ); } free(E);} /* 如果顶点有数据的话,读入数据 */ for (V=0; V<Graph->Nv; V++) scanf(" %c", &(Graph->Data[V])); return Graph; } void Visit( Vertex V ){printf("正在访问顶点%d\n", V);}/* Visited[]为全局变量,已经初始化为false */void DFS( MGraph Graph, Vertex V, void (*PVisit)(Vertex) ){/* 以V为出发点对邻接表存储的图Graph进行DFS搜索 */(*PVisit)( V ); /* 访问第V个顶点 */Visited[V] = true; /* 标记V已访问 */for(Vertex W=0;W<Graph->Nv;W++) if(!Visited[W]&&Graph->G[V][W]!=INFINITY&&V!=W) /* 对V的每个未被访问de邻接点*/DFS(Graph,W,PVisit);}int main(){for(int i=0;i<MaxVertexNum;i++)Visited[i]=false;//初始化为falseMGraph Graph=BuildGraph();DFS(Graph,0,Visit);return 0;}
用栈模拟
图的遍历之DSF深度优先算法6.2.1(网络整理)相关推荐
- 图的遍历(搜索)算法 之 深度优先遍历算法
图的遍历的定义: 从图中的某个顶点出发访问遍图中的所有顶点,并且每个顶点仅仅被访问一次. 图的遍历算法我们常见的而且用的最多的就有两种:其一是图的深度优先遍历算法:其二是图的广度优先遍历算法.这里我们 ...
- 图的遍历之BSF广度优先算法6.2.2(网络整理)
图的广度优先遍历和树的层序遍历相似,伪代码见下图: (以上图片来自网络) #include<stdlib.h> #include<stdbool.h> #include< ...
- c++ 遍历list_数据结构之图的遍历,一篇文章get全部考点
图的概念 举个例子,假设你的微信朋友圈中有若干好友:张三.李四.王五.赵六.七大姑.八大姨. 而你七大姑的微信号里,又有若干好友:你.八大姨.Jack.Rose. 微信中,许许多多的用户组成了一个多对 ...
- 动画解析:图的遍历方式有哪些?
点击关注上方"五分钟学算法", 设为"置顶或星标",第一时间送达干货. 转自景禹 小禹禹,你们好呀,景禹今天给你们说一说图的遍历方法! 小禹禹: 好呀好呀,图的 ...
- 分别用邻接矩阵和邻接表实现图的深度优先遍历和广度优先遍历_数据结构与算法学习笔记:图...
图: 图结构区别于线性结构和树型结构,区别可见下图 逻辑上的图(graph)结构由顶点(vertex)和边(edge)组成. 一个图结构G包含顶点集合V和边集合E,任何两个顶点之间可以有一个边表示两者 ...
- 分别用邻接矩阵和邻接表实现图的深度优先遍历和广度优先遍历_数据结构与算法:三十张图弄懂「图的两种遍历方式」...
原创: 进击的HelloWorld1 引言遍历是指从某个节点出发,按照一定的的搜索路线,依次访问对数据结构中的全部节点,且每个节点仅访问一次. 在二叉树基础中,介绍了对于树的遍历.树的遍历是指从根节点 ...
- 【小算法】图的遍历之深度优先(DFS)
谈到算法,图的操作是避免不了. 而我们一般谈到图时,又必定会谈到图的遍历. 图的遍历通常有 2 种,深度优先(DFS) 和广度优先(BFS). 本篇博文讲解深度优先(DFS). 图的表示 图有两种表示 ...
- 数据结构学习笔记——图的遍历算法(深度优先搜索和广度优先搜索)
目录 一.图的遍历概念 二.深度优先搜索(DFS) (一)DFS算法步骤 1.邻接表DFS算法步骤 2.邻接矩阵DFS算法步骤 (二)深度优先生成树.森林 (三)DFS的空间复杂度和时间复杂度 三.广 ...
- 获取图顶点的入度、出度;获取图的两个顶点之间的权值; 图的深度优先算法、图的广度优先遍历
广度优先结果: 深度优先结果: 代码整理: public class Graph {private int vertexSize;//顶点数量private int[] vertexs;//顶点数组p ...
- 数据结构与算法(7-2)图的遍历(深度优先遍历DFS、广度优先遍历BFS)(分别用邻接矩阵和邻接表实现)
目录 深度优先遍历(DFS)和广度优先遍历(BFS)原理 1.自己的原理图 2.官方原理图 一.邻接矩阵的深度优先遍历(DFS) 1.原理图 2. 过程: 3.总代码 二.邻接表的深度优先遍历(DFS ...
最新文章
- Nginx问题定位之监控进程异常退出
- 期望dp ---- B. Tree Array 思维+期望dp 逆序对期望数
- AI洞观 | 戴上红帽 看IBM冲杀云计算市场
- python的__init__几种方法总结【转载】
- Java-异常处理练习
- IntelliJ IDEA 快捷键(一)(window版)
- 在windows上搭建redis集群(Redis-Cluster)
- linuxpython源文件_Python3 源码安装(Linux 版)
- js嵌套函数内外层分别使用this关键字困局解
- 【笔记整理】电磁场复习——麦克斯韦四个方程组
- SketchUp 建筑分析图制作国外教程
- pythonwhile冒泡排序_python冒泡排序
- 用python做系统的感悟_《Python机器学习经典实例》学习感悟
- 病毒分析与防护实验3—— 反汇编工具(Ollydbg)的使用
- anaconda出现Multiple Errors Encountered.
- 人生有三重境界:看山是山,看水是水;看山不是山,看水不是水;看山还是山,看水还是水=
- 孙子兵法之36计详解
- 阿里云国际版服务器如何搭建区块链应用程序
- 【分享】集简云小程序识别名片到CRM流程搭建示例
- SQL DXP 6.6.x 高级版--最新版