图广度优先遍历

合集下载

图的深度广度优先遍历操作代码

图的深度广度优先遍历操作代码

一、实验目的1.掌握图的各种存储结构,特别要熟练掌握邻接矩阵和邻接表存储结构;2.遍历是图各种应用的算法的基础,要熟练掌握图的深度优先遍历和宽度优先遍历算法,复习栈和队列的应用;3.掌握图的各种应用的算法:图的连通性、连通分量和最小生成树、拓扑排序、关键路径。

二、实验内容实验内容1**图的遍历[问题描述]许多涉及图上操作的算法都是以图的遍历为基础的。

写一个程序,演示在连通无向图上遍历全部顶点。

[基本要求]建立图的邻接表的存储结构,实现无向图的深度优先遍历和广度优先遍历。

以用户指定的顶点为起点,分别输出每种遍历下的顶点访问序列。

[实现提示]设图的顶点不超过30个,每个顶点用一个编号表示(如果一个图有N个顶点,则它们的编号分别为1,2,…,N)。

通过输入图的全部边输入一个图,每条边是两个顶点编号对,可以对边依附顶点编号的输入顺序作出限制(例如从小到大)。

[编程思路]首先图的创建,采用邻接表建立,逆向插入到单链表中,特别注意无向是对称插入结点,且要把输入的字符在顶点数组中定位(LocateVex(Graph G,char *name),以便后来的遍历操作,深度遍历算法采用递归调用,其中最主要的是NextAdjVex(Graph G, int v, int w);FirstAdjVex ()函数的书写,依次递归下去,广度遍历用队列的辅助。

[程序代码]头文件:#include<stdio.h>#include<stdlib.h>#define MAX_VERTEX_NUM 30#define MAX_QUEUE_NUMBER 30#define OK 1#define ERROR 0#define INFEASIBLE -1#define OVERFLOW -2#define TRUE 1#define FALSE 0typedef int Status;typedef int InfoType;typedef int Status;/* 定义弧的结构*/typedef struct ArcNode{int adjvex; /*该边所指向的顶点的位置*/ struct ArcNode *nextarc; /*指向下一条边的指针*/ InfoType info; /*该弧相关信息的指针*/}ArcNode;/*定义顶点的结构*/typedef struct VNode{char data[40]; /*顶点信息*/ArcNode *firstarc; /*指向第一条依附该顶点的弧的指针*/}VNode,AdjList[MAX_VERTEX_NUM];/*定义图的结构*/typedef struct {AdjList vertices;int vexnum,arcnum; /*图的当前顶点数和弧数*/int kind; /*图的类型标志*/}Graph;/*定义队列的结构*/typedef struct{int *elem;int front, rear;}Queue;/*功能选择*/void MenuSelect(int w);/*顶点定位*/int LocateVex(Graph G,char *name);/*创建无向图*/void CreateGraph(Graph &G);/*求第一个顶点*/int FirstAdjVex(Graph G, int v);/*求下一个顶点*/int NextAdjVex(Graph G, int v, int w);/*深度递归*/void DFS(Graph G, int v) ;/*深度遍历*/void DFSTravel(Graph G,int v);/*广度遍历*/void BFSTraverse(Graph G,char *name);/*初始化队列*/Status InitQueue(Queue &Q);/*判空*/Status EmptyQueue(Queue Q);/*进队*/Status EnQueue(Queue &Q, int e);/*出队*/Status DeQueue(Queue &Q, int &e);实现文件:#include <stdio.h>#include"malloc.h"#include "tuhead.h"#include "stdlib.h"#include "string.h"bool visited[MAX_VERTEX_NUM];/************************************************************ 顶点定位************************************************************/int LocateVex(Graph G,char *name){int i;for(i=1;i<=G.vexnum;i++) //从1号位置开始存储if(strcmp(name,G.vertices[i].data)==0) //相等则找到,返回位序return i;return -1;}/************************************************************ 创建无向图************************************************************/void CreateGraph(Graph &G){ArcNode *p;char name1[10],name2[10];int i,j,k;printf(" 请输入顶点数,按回车键结束:");scanf("%d",&G.vexnum);printf(" 请输入弧数,按回车键结束:");scanf("%d",&G.arcnum);printf(" 请依次输入顶点名(用空格分开且字符小于10),按回车键结束:\n");printf(" ");for(i=1;i<=G.vexnum;i++) //从1号位置开始存储{scanf("%s",G.vertices[i].data); //从一号位置开始初始化G.vertices[i].firstarc=NULL;}printf("\n\n\n\n");printf(" ………………………………………输入小提示………………………………………\n");printf(" &&&&1 为避免输入遗漏,最好从选择任意一点,输入所有相邻边\n");printf(" &&&&2 输入边时格式(用空格分开,即格式为顶点(空格)顶点(空格))\n");printf(" ………………………………………输入小提示………………………………………\n\n\n\n");for(k=0;k<G.arcnum;k++){printf("请输入相邻的两个顶点,按回车键结束:");scanf("%s%s",name1,name2);i=LocateVex(G,name1); //返回位序j=LocateVex(G,name2);p=(ArcNode *)malloc(sizeof(ArcNode)); //申请边节点p->adjvex=j; //插入到邻接表中,注意此处为逆向插入到单链表中p->nextarc=G.vertices[i].firstarc;G.vertices[i].firstarc=p;//无向图,注意是对称插入结点p=(ArcNode *)malloc(sizeof(ArcNode));p->adjvex=i;p->nextarc=G.vertices[j].firstarc;G.vertices[j].firstarc=p;}}/************************************************************ 求第一个顶点************************************************************/int FirstAdjVex(Graph G, int v){ArcNode *p;if(v>=1 && v<=G.vexnum){p=G.vertices[v].firstarc;if(p->nextarc==NULL)return 0;elsereturn (p->nextarc->adjvex); //返回第一个顶点字符}return -1;}/************************************************************ 求下一个顶点************************************************************/int NextAdjVex(Graph G, int v, int w){ //在图G中寻找第v个顶点的相对于w的下一个邻接顶点ArcNode *p;if(v>=1 && v<=G.vexnum && w>=1 && w<=G.vexnum){p=G.vertices[v].firstarc;while(p->adjvex!=w)p=p->nextarc; //在顶点v的弧链中找到顶点wif(p->nextarc!=NULL)return 0; //若已是最后一个顶点,返回0 elsereturn(p->nextarc->adjvex); //返回下一个邻接顶点的序号}return -1;}/************************************************************ 深度递归************************************************************/void DFS(Graph G, int v){int w;ArcNode *p;visited[v]=1;printf("%s ",G.vertices[v].data); //访问第v个顶点p=G.vertices[v].firstarc; //p为依附顶点的第一条边while (p!=NULL){w=p->adjvex;if(visited[w]==0)DFS(G,w);p=p->nextarc; //下移指针}}/************************************************************ 深度遍历************************************************************/void DFSTravel(Graph G,int v){for(int i=1;i<=G.vexnum;i++)visited[i]=0;int w;ArcNode *p;visited[v]=1;printf("%s ",G.vertices[v].data); //访问第v个顶点p=G.vertices[v].firstarc;while (p!=NULL){w=p->adjvex;if(visited[w]==0)DFS(G,w);p=p->nextarc;}}/************************************************************ 初始化队列************************************************************/Status InitQueue(Queue &Q){Q.elem = new int[MAX_QUEUE_NUMBER];Q.front = Q.rear = 0;return OK;}Status EmptyQueue(Queue Q){if(Q.front==Q.rear)return 0;elsereturn 1;}/*********************************************************** * 进队列* ***********************************************************/ Status EnQueue(Queue &Q, int e){if((Q.rear + 1)%MAX_QUEUE_NUMBER != Q.front)Q.elem[Q.rear ] = e;else ;Q.rear = (Q.rear + 1)%MAX_QUEUE_NUMBER;return OK;}/*********************************************************** * 出队列* ***********************************************************/ Status DeQueue(Queue &Q, int &e){if(Q.rear != Q.front)e = Q.elem[Q.front];else ;Q.front = (Q.front+1)%MAX_QUEUE_NUMBER;return OK;}/*********************************************************** * 广度遍历************************************************************/void BFSTraverse(Graph G,char *name){ArcNode *p;int v,w,u,k=0;Queue Q;int visited[20];for(v=1;v<=G.vexnum;v++) //初始化visited[v]=0;InitQueue(Q);for(v=LocateVex(G,name);k!=2;v=(v+1)%(G.vexnum-1)) //v为输入的字符转化的位序{if(v+1==LocateVex(G,name)) //从v开始走完图的所有顶点k++;if(visited[v]==0){visited[v]=1;printf("%s ",G.vertices[v].data); //访问第v个顶点EnQueue(Q,v); // 进队while(EmptyQueue(Q)!=0){DeQueue(Q,u); //出队p=G.vertices[u].firstarc;while(p!=NULL){w=p->adjvex; //p边的下一个顶点if(visited[w]==0){printf("%s ",G.vertices[w].data);visited[w]=1;EnQueue(Q,w);}p=p->nextarc; //下移指针}}}}}主文件:#include <stdio.h>#include"malloc.h"#include "tuhead.h"#include "stdlib.h"#include "string.h"/************************************************************ 界面控制************************************************************/void main(){printf("\n################################# 图的遍历#################################\n");printf("\n $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$\n");printf("\n");printf(" 1 ------- 图的创建\n");printf(" 2 ------- 图的深度优先遍历\n");printf(" 3 ------- 图的广度优先遍历\n");printf(" 0 ------- 退出\n");printf("\n $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$\n");printf("\n");printf("请输入选择的操作代码(0-3)按回车键结束\n");MenuSelect(1);}/************************************************************ 功能选择************************************************************/void MenuSelect(int w){int select,done;int v;Graph G; char name[10];while (done) {printf("input the operating code : ");scanf("%d",&select);switch(select){case 1: printf("根据要求创建图:\n ");CreateGraph(G);break;case 2: printf("请输入深度优先遍历开始点的名:");scanf("%s",name);v=LocateVex(G,name); //将输入字符找到在顶点数组name对应的序号Vprintf("深度优先遍历:");DFSTravel(G,v);printf("\n");break;case 3: printf("请输入广度优先遍历开始点的名:");scanf("%s",name);printf("广度优先遍历:");BFSTraverse(G,name);printf("\n");break;case 0: done=0; break;default: printf(" ERROR\n");}printf("\n");}}[实验数据与结果]测试数据:实验结果。

第7章图的深度和广度优先搜索遍历算法

第7章图的深度和广度优先搜索遍历算法
7.3 图的遍历
和树的遍历类似,我们希望从图中某顶点出发对图中每个顶点访问一次,而且只访问 一次,这一过程称为图的遍历(traversing graph)。 本节介绍两种遍历图的规则:深度优先搜索和广度优先搜索。 这两种方法既适用于无向图,也适用于有向图。
7.3.1 深度优先搜索遍历 一.思路: 从图中某一点(如A)开始,先访问这一点,然后任选它的一个邻点(如V0) 访问,访问完该点后,再任选这个点V0的一个邻点 ( 如 W )访问,如此向 纵深方向访问。直到某个点没有其他未访问的邻点为止,则返回到前一个点。 再任选它的另一个未访问过的邻点 ( 如X )继续重复上述过程的访问,直到全 部点访问完为止。 图(a)的遍历的结果:V1V2V4V8V5V3V6V7 或V1V3V7V6V2V5V8V4
p
v0 w x v 1
V
0
v 2
V
0
typedef struct {VEXNODE adjlist[MAXLEN]; // 邻接链表表头向量 int vexnum, arcnum; // 顶点数和边数 int kind; // 图的类型 }ADJGRAPH;
W W
X
X
7.3.2 广度优先搜索遍历 一.思路:
V
0
A V
0
W W
XXΒιβλιοθήκη 二.深度优先搜索算法的文字描述: 算法中设一数组visited,表示顶点是否访问过的标志。数组长度为 图的顶点数,初值均置为0,表示顶点均未被访问,当Vi被访问过,即 将visitsd对应分量置为1。将该数组设为全局变量。 { 确定从G中某一顶点V0出发,访问V0; visited[V0] = 1; 找出G中V0的第一个邻接顶点->w; while (w存在) do { if visited[w] == 0 继续进行深度优先搜索; 找出G中V0的下一个邻接顶点->w;} }

【免费下载】邻接矩阵表示图 深度 广度优先遍历

【免费下载】邻接矩阵表示图 深度 广度优先遍历
A[i,j]={ 0,反之
图 5-2 中有向图 G1 的邻接矩阵为 M1 M1=┌ 0 1 0 1 ┐
│1010│ │1001│ └0000┘
用邻接矩阵表示法来表示一个具有 n 个顶点的图时,除了用邻接矩阵中的 n*n 个元素存储顶点间相邻关系外,往往还需要另设一个向量存储 n 个顶点的 信息。因此其类型定义如下: VertexType vertex[MAX_VERTEX_NUM]; // 顶点向量
易求得各个顶点的度。
对于有向图,顶点 Vi 的出度 OD(Vi)为邻接矩阵第 i 行元素之和,顶点 Vi 的入度 ID(Vi)为第 i 列元素之和。即 n n OD(Vi)=∑A[i,j], OD(Vi)=∑A[j,i]) j=1 j=1 用邻接矩阵也可以表示带权图,只要令 Wij, 若<Vi,Vj>或(Vi,Vj) A[i,j]={ ∞ , 否则。 其中 Wij 为<Vi,Vj>或(Vi,Vj)上的权值。相应地,网的邻接矩阵表示的类型 定义应作如下的修改: adj:weightype ; {weightype 为权类型}
2、图的遍历: *深度优先搜索
深度优先搜索遍历类似于树的先根遍历,是树的先根遍历的推广。假设初 始状态是图中所有的顶点未曾被访问,则深度优先遍历可从图的某个顶点 V 出 发,访问此顶点,然后依次从 V 的未被访问的邻接点出发深度优先遍历图,直 至图中所有和 V 有路径相通的顶点都被访问到;若此时图中尚有顶点未被访问, 则另选图中的一个未被访问的顶点,重复上述过程,直至图中所有顶点都被访 问到为止。
以图中无向图 G4 为例,深度优先遍历图的过程如图所示。假设从顶点 V1 出 发进行搜索,在访问了顶点 V1 后,选择邻接点 V2。因为 V2 未曾访问,则从 V2 出发进行搜索。依次类推,接着从 V4,V8,V5 出发进行搜索。在访问了 V5 之后, 由于 V5 的邻接点已都被访问,则搜索回到 V8。由于同样的理由,搜索继续回到 V4,V2 直至 V1,此时由于 V1 的另一个邻接点为被访问,则搜索又从 V1 到 V3,再

广度优先遍历非递归算法

广度优先遍历非递归算法

广度优先遍历非递归算法
广度优先遍历(BFS)是一种图的遍历算法,用来遍历图中所有的节点。

以下是广度优先遍历的非递归算法:
1. 创建一个队列,用来存放待访问的节点。

2. 将起始节点放入队列中。

3. 创建一个集合,用来存放已经访问过的节点。

4. 将起始节点加入到已访问节点的集合中。

5. 循环执行以下步骤,直到队列为空为止:
5.1. 从队列中取出一个节点。

5.2. 访问该节点。

5.3. 获取该节点的所有相邻节点。

5.4. 对于每个相邻节点,如果它没有被访问过,则将其加入到队列和已访问节点的集合中。

通过以上步骤,可以按广度优先的顺序遍历整个图。

这种非递归算法利用队列的先进先出(FIFO)特性,保证了相邻节点的访问顺序是按照它们与起始节点的距离逐渐增加的顺序进行的,从而实现了广度优先遍历。

深度优先搜索和广度优先搜索

深度优先搜索和广度优先搜索

深度优先搜索和⼴度优先搜索 深度优先搜索和⼴度优先搜索都是图的遍历算法。

⼀、深度优先搜索(Depth First Search) 1、介绍 深度优先搜索(DFS),顾名思义,在进⾏遍历或者说搜索的时候,选择⼀个没有被搜过的结点(⼀般选择顶点),按照深度优先,⼀直往该结点的后续路径结点进⾏访问,直到该路径的最后⼀个结点,然后再从未被访问的邻结点进⾏深度优先搜索,重复以上过程,直⾄所有点都被访问,遍历结束。

⼀般步骤:(1)访问顶点v;(2)依次从v的未被访问的邻接点出发,对图进⾏深度优先遍历;直⾄图中和v有路径相通的顶点都被访问;(3)若此时图中尚有顶点未被访问,则从⼀个未被访问的顶点出发,重新进⾏深度优先遍历,直到图中所有顶点均被访问过为⽌。

可以看出,深度优先算法使⽤递归即可实现。

2、⽆向图的深度优先搜索 下⾯以⽆向图为例,进⾏深度优先搜索遍历: 遍历过程: 所以遍历结果是:A→C→B→D→F→G→E。

3、有向图的深度优先搜索 下⾯以有向图为例,进⾏深度优先遍历: 遍历过程: 所以遍历结果为:A→B→C→E→D→F→G。

⼆、⼴度优先搜索(Breadth First Search) 1、介绍 ⼴度优先搜索(BFS)是图的另⼀种遍历⽅式,与DFS相对,是以⼴度优先进⾏搜索。

简⾔之就是先访问图的顶点,然后⼴度优先访问其邻接点,然后再依次进⾏被访问点的邻接点,⼀层⼀层访问,直⾄访问完所有点,遍历结束。

2、⽆向图的⼴度优先搜索 下⾯是⽆向图的⼴度优先搜索过程: 所以遍历结果为:A→C→D→F→B→G→E。

3、有向图的⼴度优先搜索 下⾯是有向图的⼴度优先搜索过程: 所以遍历结果为:A→B→C→E→F→D→G。

三、两者实现⽅式对⽐ 深度优先搜索⽤栈(stack)来实现,整个过程可以想象成⼀个倒⽴的树形:把根节点压⼊栈中。

每次从栈中弹出⼀个元素,搜索所有在它下⼀级的元素,把这些元素压⼊栈中。

并把这个元素记为它下⼀级元素的前驱。

数据结构课设——有向图的深度、广度优先遍历及拓扑排序

数据结构课设——有向图的深度、广度优先遍历及拓扑排序

数据结构课设——有向图的深度、⼴度优先遍历及拓扑排序任务:给定⼀个有向图,实现图的深度优先, ⼴度优先遍历算法,拓扑有序序列,并输出相关结果。

功能要求:输⼊图的基本信息,并建⽴图存储结构(有相应提⽰),输出遍历序列,然后进⾏拓扑排序,并测试该图是否为有向⽆环图,并输出拓扑序列。

按照惯例,先上代码,注释超详细:#include<stdio.h>#include<stdlib.h>#include<malloc.h>#pragma warning(disable:4996)#define Max 20//定义数组元素最⼤个数(顶点最⼤个数)typedef struct node//边表结点{int adjvex;//该边所指向结点对应的下标struct node* next;//该边所指向下⼀个结点的指针}eNode;typedef struct headnode//顶点表结点{int in;//顶点⼊度char vertex;//顶点数据eNode* firstedge;//指向第⼀条边的指针,边表头指针}hNode;typedef struct//邻接表(图){hNode adjlist[Max];//以数组的形式存储int n, e;//顶点数,边数}linkG;//以邻接表的存储结构创建图linkG* creat(linkG* g){int i, k;eNode* s;//边表结点int n1, e1;char ch;g = (linkG*)malloc(sizeof(linkG));//申请结点空间printf("请输⼊顶点数和边数:");scanf("%d%d", &n1, &e1);g->n = n1;g->e = e1;printf("顶点数:%d 边数:%d\n", g->n, g->e);printf("请输⼊顶点信息(字母):");getchar();//因为接下来要输⼊字符串,所以getchar⽤于承接上⼀条命令的结束符for (i = 0; i < n1; i++){scanf("%c", &ch);g->adjlist[i].vertex = ch;//获得该顶点数据g->adjlist[i].firstedge = NULL;//第⼀条边设为空}printf("\n打印顶点下标及顶点数据:\n");for (i = 0; i < g->n; i++)//循环打印顶点下标及顶点数据{printf("顶点下标:%d 顶点数据:%c\n", i, g->adjlist[i].vertex);}getchar();int i1, j1;//相连接的两个顶点序号for (k = 0; k < e1; k++)//建⽴边表{printf("请输⼊对<i,j>(空格分隔):");scanf("%d%d", &i1, &j1);s = (eNode*)malloc(sizeof(eNode));//申请边结点空间s->adjvex = j1;//边所指向结点的位置,下标为j1s->next = g->adjlist[i1].firstedge;//将当前s的指针指向当前顶点上指向的结点g->adjlist[i1].firstedge = s;//将当前顶点的指针指向s}return g;//返回指针g}int visited[Max];//标记是否访问void DFS(linkG* g, int i)//深度优先遍历{eNode* p;printf("%c ", g->adjlist[i].vertex);visited[i] = 1;//将已访问过的顶点visited值改为1p = g->adjlist[i].firstedge;//p指向顶点i的第⼀条边while (p)//p不为NULL时(边存在){if (visited[p->adjvex] != 1)//如果没有被访问DFS(g, p->adjvex);//递归}p = p->next;//p指向下⼀个结点}}void DFSTravel(linkG* g)//遍历⾮连通图{int i;printf("深度优先遍历;\n");//printf("%d\n",g->n);for (i = 0; i < g->n; i++)//初始化为0{visited[i] = 0;}for (i = 0; i < g->n; i++)//对每个顶点做循环{if (!visited[i])//如果没有被访问{DFS(g, i);//调⽤DFS函数}}}void BFS(linkG* g, int i)//⼴度优先遍历{int j;eNode* p;int q[Max], front = 0, rear = 0;//建⽴顺序队列⽤来存储,并初始化printf("%c ", g->adjlist[i].vertex);visited[i] = 1;//将已经访问过的改成1rear = (rear + 1) % Max;//普通顺序队列的话,这⾥是rear++q[rear] = i;//当前顶点(下标)队尾进队while (front != rear)//队列⾮空{front = (front + 1) % Max;//循环队列,顶点出队j = q[front];p = g->adjlist[j].firstedge;//p指向出队顶点j的第⼀条边while (p != NULL){if (visited[p->adjvex] == 0)//如果未被访问{printf("%c ", g->adjlist[p->adjvex].vertex);visited[p->adjvex] = 1;//将该顶点标记数组值改为1rear = (rear + 1) % Max;//循环队列q[rear] = p->adjvex;//该顶点进队}p = p->next;//指向下⼀个结点}}}void BFSTravel(linkG* g)//遍历⾮连通图{int i;printf("⼴度优先遍历:\n");for (i = 0; i < g->n; i++)//初始化为0{visited[i] = 0;}for (i = 0; i < g->n; i++)//对每个顶点做循环{if (!visited[i])//如果没有被访问过{BFS(g, i);//调⽤BFS函数}}}//因为拓扑排序要求⼊度为0,所以需要先求出每个顶点的⼊度void inDegree(linkG* g)//求图顶点⼊度{eNode* p;int i;for (i = 0; i < g->n; i++)//循环将顶点⼊度初始化为0{g->adjlist[i].in = 0;}for (i = 0; i < g->n; i++)//循环每个顶点{p = g->adjlist[i].firstedge;//获取第i个链表第1个边结点指针while (p != NULL)///当p不为空(边存在){g->adjlist[p->adjvex].in++;//该边终点结点⼊度+1p = p->next;//p指向下⼀个边结点}printf("顶点%c的⼊度为:%d\n", g->adjlist[i].vertex, g->adjlist[i].in);}void topo_sort(linkG *g)//拓扑排序{eNode* p;int i, k, gettop;int top = 0;//⽤于栈指针的下标索引int count = 0;//⽤于统计输出顶点的个数int* stack=(int *)malloc(g->n*sizeof(int));//⽤于存储⼊度为0的顶点for (i=0;i<g->n;i++)//第⼀次搜索⼊度为0的顶点{if (g->adjlist[i].in==0){stack[++top] = i;//将⼊度为0的顶点进栈}}while (top!=0)//当栈不为空时{gettop = stack[top--];//出栈,并保存栈顶元素(下标)printf("%c ",g->adjlist[gettop].vertex);count++;//统计顶点//接下来是将邻接点的⼊度减⼀,并判断该点⼊度是否为0p = g->adjlist[gettop].firstedge;//p指向该顶点的第⼀条边的指针while (p)//当p不为空时{k = p->adjvex;//相连接的顶点(下标)g->adjlist[k].in--;//该顶点⼊度减⼀if (g->adjlist[k].in==0){stack[++top] = k;//如果⼊度为0,则进栈}p = p->next;//指向下⼀条边}}if (count<g->n)//如果输出的顶点数少于总顶点数,则表⽰有环{printf("\n有回路!\n");}free(stack);//释放空间}void menu()//菜单{system("cls");//清屏函数printf("************************************************\n");printf("* 1.建⽴图 *\n");printf("* 2.深度优先遍历 *\n");printf("* 3.⼴度优先遍历 *\n");printf("* 4.求出顶点⼊度 *\n");printf("* 5.拓扑排序 *\n");printf("* 6.退出 *\n");printf("************************************************\n");}int main(){linkG* g = NULL;int c;while (1){menu();printf("请选择:");scanf("%d", &c);switch (c){case1:g = creat(g); system("pause");break;case2:DFSTravel(g); system("pause");break;case3:BFSTravel(g); system("pause");break;case4:inDegree(g); system("pause");break;case5:topo_sort(g); system("pause");break;case6:exit(0);break;}}return0;}实验⽤图:运⾏结果:关于深度优先遍历 a.从图中某个顶点v 出发,访问v 。

图的遍历技巧

图的遍历技巧

图的遍历技巧
图的遍历是指按照一定的规则,从图的某个顶点出发,沿着边遍历图中的所有顶点,使得每个顶点都被访问一次且仅一次的过程。

常用的图的遍历技巧有以下两种:
1. 深度优先遍历(Depth First Search, DFS):从图的某个顶点出发,先访问该顶点,然后依次访问与该顶点相邻的未被访问过的顶点,并以此递归地进行遍历。

当不存在未被访问的相邻顶点时,回溯到上一个顶点,继续遍历其他未被访问的相邻顶点,直至所有顶点都被访问完。

2. 广度优先遍历(Breadth First Search, BFS):从图的某个顶点出发,先访问该顶点,然后依次访问与该顶点相邻的未被访问过的顶点,并将这些顶点按照入队的顺序加入队列中。

接下来再从队列中取出一个顶点,重复前述操作,直至队列为空。

这两种遍历技巧可以分别应用于不同场景的图问题。

深度优先遍历一般适用于需要探索整个图中某一支路径的问题,而广度优先遍历一般适用于需要确定最短路径或者按层遍历的问题。

图的两种遍历

图的两种遍历

输入:
9 10 12 13 17 28 27 34 45 47 56 ram xy; var map:array[1..20,1..20] of integer; visited,q:array[1..100] of integer; //使用辅助队列Q和访问标志数组visited。 n,m,a,b,h,r,i,j:integer; procedure bfs(); //按广度优先非递归遍历图,n个顶点,编号为1..n。 var tmp:integer; begin while h<=r do begin tmp:=q[h]; //队头元素出队并置为tmp h:=h+1; write(tmp,' '); for j:=1 to n do if (map[tmp][j]=1) and (visited[j]=0) then //j为tmp的尚未访问的邻接顶点 begin visited[j]:=1;r:=r+1;q[r]:=j; end;//j入队列 end; end;
保证图中所有 顶点被访问
三、广(宽)度优先遍历
宽度优先遍历的基本思想为:
从图中某个顶点v0出发,访问此顶点。然后依次访问v0的 各个未被访问过的邻接结点,然后分别从这些邻接结点出发 宽度优先遍历图,直到图中所有和顶点v0连通的顶点都被访 问到。 若此时图中尚有顶点未被访问,则另选图中一个未曾被访 问的顶点作起始点,重复上述过程,直到图中所有顶点都被 访问到为止。
begin readln(n,m); for i:=1 to m do begin readln(a,b); map[a][b]:=1; map[b][a]:=1; end; for i:=1 to n do if visited[i]=0 then begin visited[i]:=1;work(i);end; end.
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

v2 v3 v1 v4 v1 v6 v2 v8 v2 v8 v3 v7 v3 v6 v4 v5
队列
v5
v2 v3
v7
v1 v2 v3
图广度优先遍历
0 1 v1 2 v2 3 V3 4 V4 5 v5 6 v6 7 v7 8 v8
v2 v3 v1 v4 v1 v6 v2 v8 v2 v8 v3 v7 v3 v6 v4 v5
0
1 v1 v2
v1
2 v2 v1
v2
பைடு நூலகம்
v3
3 V3 v1
v4
v5
v6
4 V4 v2
v7 5 v5
v2
v8
6 v6 v3
7 v7 v3
8 v8 v4
图广度优先遍历
v3 v4 v5 v6 v7 v8 v8 v7 v6 v5
演示开始,以v1为遍历的起点
图广度优先遍历
0 1 v1 2 v2 3 V3 4 V4 5 v5 6 v6 7 v7 8 v8
v2 v3 v1 v4 v1 v6 v2 v8 v2 v8 v3 v7 v3 v6 v4 v5
队列
v5
v3 v4 v5
v7
v1 v2 v3 v4 v5
图广度优先遍历
0 1 v1 2 v2 3 V3 4 V4 5 v5 6 v6 7 v7 8 v8
v2 v3 v1 v4 v1 v6 v2 v8 v2 v8 v3 v7 v3 v6 v4 v5
队列
v5
v3
v7
v2
v1 v2 v3 v4
V2的邻接点v4没 有被访问过,访 问之,且入队列
图广度优先遍历
0 1 v1 2 v2 3 V3 4 V4 5 v5 6 v6 7 v7 8 v8
v2 v3 v1 v4 v1 v6 v2 v8 v2 v8 v3 v7 v3 v6 v4 v5
队列
v5
v3 v4
队列 v1
v5 v7
V1入队列
v1
图广度优先遍历
0 1 v1 2 v2 3 V3 4 V4 5 v5 6 v6 7 v7 8 v8
v2 v3 v1 v4 v1 v6 v2 v8 v2 v8 v3 v7 v3 v6 v4 v5
队列
v5 v7
v1 v1
图广度优先遍历
取队头元素
0 1 v1 2 v2 3 V3 4 V4 5 v5 6 v6 7 v7 8 v8
v2 v3 v1 v4 v1 v6 v2 v8 v2 v8 v3 v7 v3 v6 v4 v5
队列
v5 v7
v1 访问v1
图广度优先遍历
0 1 v1 2 v2 3 V3 4 V4 5 v5 6 v6 7 v7 8 v8
v2 v3 v1 v4 v1 v6 v2 v8 v2 v8 v3 v7 v3 v6 v4 v5
图广度优先遍历
0 1 v1 2 v2 3 V3 4 V4 5 v5 6 v6 7 v7 8 v8
v2 v3 v1 v4 v1 v6 v2 v8 v2 v8 v3 v7 v3 v6 v4 v5
队列
v5
v2 v3
v7
v1
v1 v2 v3
图广度优先遍历
0 1 v1 2 v2 3 V3 4 V4 5 v5 6 v6 7 v7 8 v8
v7
v2
v1 v2 v3 v4
图广度优先遍历
0 1 v1 2 v2 3 V3 4 V4 5 v5 6 v6 7 v7 8 v8
v2 v3 v1 v4 v1 v6 v2 v8 v2 v8 v3 v7 v3 v6 v4 v5
队列
v5
v3 v4
v7
v2
v1 v2 v3 v4 v5
V2的邻接点v5没 有被访问过,访 问之,且入队列
v2 v3 v1 v4 v1 v6 v2 v8 v2 v8 v3 v7 v3 v6 v4 v5
队列
v5 v7
v1 v1 v2
图广度优先遍历
V1的邻接点v2没 有被访问过,访 问之,且入队列
0 1 v1 2 v2 3 V3 4 V4 5 v5 6 v6 7 v7 8 v8
v2 v3 v1 v4 v1 v6 v2 v8 v2 v8 v3 v7 v3 v6 v4 v5
队列
v5
v3
v7
v2
v1 v2 v3
图广度优先遍历
0 1 v1 2 v2 3 V3 4 V4 5 v5 6 v6 7 v7 8 v8
v2 v3 v1 v4 v1 v6 v2 v8 v2 v8 v3 v7 v3 v6 v4 v5
队列
v5
v3
v7
v2
v1 v2 v3
图广度优先遍历
0 1 v1 2 v2 3 V3 4 V4 5 v5 6 v6 7 v7 8 v8
7.3.2.连通图的广度优先遍历
图广度优先遍历
算法描述:
1.广度优先遍历以x开始的连通图
① 访问X,且x入队列 ② 若队列不空,重复以下步骤 ③ 取队头元素并放入v中 ④ 考察v的各个邻接点,若未访问,
则先访问,然后放在队列尾部 ⑤ 返回步骤②
图广度优先遍历
2.算法演示
图广度优先遍历
例图及其邻接表表示
队列
v5
v2
v7
v1
v1 v2
图广度优先遍历
0 1 v1 2 v2 3 V3 4 V4 5 v5 6 v6 7 v7 8 v8
v2 v3 v1 v4 v1 v6 v2 v8 v2 v8 v3 v7 v3 v6 v4 v5
队列
v5
v2
v7
v1
v1 v2 v3
图广度优先遍历
V1的邻接点v3没 有被访问过,访 问之,且入队列
v2 v3 v1 v4 v1 v6 v2 v8 v2 v8 v3 v7 v3 v6 v4 v5
队列
v5
v3
v7
v2
v1 v2 v3
图广度优先遍历
V2的邻接点v1已 经被访问过不再
访问
0 1 v1 2 v2 3 V3 4 V4 5 v5 6 v6 7 v7 8 v8
v2 v3 v1 v4 v1 v6 v2 v8 v2 v8 v3 v7 v3 v6 v4 v5
队列
v5
v4 v5
v7
v3
v1 v2 v3 v4 v5
图广度优先遍历
0 1 v1 2 v2 3 V3 4 V4 5 v5 6 v6 7 v7 8 v8
v2 v3 v1 v4 v1 v6 v2 v8 v2 v8 v3 v7 v3 v6 v4 v5
队列
v5
v4 v5
v7
v3
v1 v2 v3 v4 v5
图广度优先遍历
0 1 v1 2 v2 3 V3 4 V4 5 v5 6 v6 7 v7 8 v8
v2 v3 v1 v4 v1 v6 v2 v8 v2 v8 v3 v7 v3 v6 v4 v5
队列
v5
v3 v4 v5
v7
v2
v1 v2 v3 v4 v5
图广度优先遍历
0 1 v1 2 v2 3 V3 4 V4 5 v5 6 v6 7 v7 8 v8
相关文档
最新文档