图的遍历

合集下载

图的遍历算法

图的遍历算法

1图的遍历问题在实践中常常遇到这样的问题:给定n个点,从任一点出发对所有的点访问一次并且只访问一次。

如果用图中的顶点表示这些点,图中的边表示可能的连接,那么这个问题就可以表示成图的遍历问题,即从某个顶点出发,沿着某条搜索路径对图中每个顶点各做一次且仅做一次访问。

图的遍历操作和树的遍历操作功能相似,是图的一种基本操作,图的许多其它操作都是建立在遍历操作的基础上。

由于图结构本身的复杂性,所以图的遍历操作也比较复杂,主要表现在以下几个方面:(1) 在图结构中,没有一个确定的首结点,图中任意一个顶点都可以作为第一个被访问的结点。

(2) 在非连通图中,从一个顶点出发,只能够访问它所在的连通分量上的所有顶点,因此,还需要考虑如何选取下一个出发点以访问图中其余的连通分量。

(3) 在图结构中,如果有回路存在,那么一个顶点被访问后,有可能沿回路又回到该顶点。

⑷在图结构中,一个顶点可以和其它多个顶点相连,当这样的顶点访问过后,存在如何选取下一个要访问的顶点的问题。

基于以上分析,图的遍历方法目前有深度优先搜索(DFS)和广度优先搜索(BFS)两种算法。

下面将介绍两种算法的实现思路,分析算法效率并编程实现。

1.1深度优先搜索算法深度优先搜索算法是树的先根遍历的推广,它的实现思想是:从图G的某个顶点V o出发,访问V o,然后选择一个与V o相邻且没被访问过的顶点V i访问,再从V i出发选择一个与V i相邻且未被访问的顶点V j进行访问,依次继续。

如果当前被访问过的顶点的所有邻接顶点都已被访问,贝U退回已被访问的顶点序列中最后一个拥有未被访问的相邻顶点的顶点W,从W出发按同样的方法向前遍历,直到图中所有顶点都被访问。

其递归算法如下:Boolean visited[MAX_VERTEX_NUM]; // 访问标志数组Status (*VisitFunc)(int v); //VisitFunc是访问函数,对图的每个顶点调用该函数void DFSTraverse (Graph G Status(*Visit)(i nt v)){VisitF unc = Visit;for(v=0; vvG.vex num; ++v)visited[v] = FALSE; //访问标志数组初始化for(v=0; v<G .vex num; ++v)if(!visited[v])DFS(G v); //对尚未访问的顶点调用DFS}void DFS(Graph G int v){ //从第v个顶点出发递归地深度优先遍历图Gvisited[v]=TRUE; VisitFunc(v); // 访问第v 个顶点for(w=FirstAdjVex(G ,v); w>=0;w=NextAdjVex(G ,v,w))//FirstAdjVex返回v的第一个邻接顶点,若顶点在G中没有邻接顶点,则返回空(0)。

第15讲图的遍历

第15讲图的遍历

V6
V8
V8
V7
V5 深度优先生成树
V8 V1
V2
V3
V4 V5 V6 V7
V8 广度优先生成树
27
例A
B
CD E
F
GH
I
K
J
L
M
A
D
G
LCF
KI E
H M
JB
深度优先生成森林
28
二、图的连通性问题
▪1、生成树和生成森林
▪ 说明
G
▪ 一个图可以有许多棵不同的生成树
KI
▪ 所有生成树具有以下共同特点:
g.NextAdjVex(v, w))
{
if (g.GetTag(w) == UNVISITED)
{
g.SetTag(w, VISITED);
g.GetElem(w, e);
Visit(e);
q.InQueue(w);
}
}}}
24
一、图的遍历 两种遍历的比较
V0
V1 V4
V0
V1 V4
V3
V2 V5
16
一、图的遍历
广度优先遍历序列?入队序列?出队序列?
V1
V2
V3
V1
V4
V5 V6
V7
V8
遍历序列: V1
17
一、图的遍历
广度优先遍历序列?入队序列?出队序列?
V1
V2
V3
V2 V3
V4
V5 V6
V7
V8
遍历序列: V1 V2 V3
18
一、图的遍历
广度优先遍历序列?入队序列?出队序列?
V1
V2

数据结构实验报告图的遍历

数据结构实验报告图的遍历

数据结构实验报告图的遍历一、实验目的本实验旨在通过实践的方式学习图的遍历算法,掌握图的深度优先搜索(DFS)和广度优先搜索(BFS)的实现方法,加深对数据结构中图的理解。

二、实验步骤1. 创建图的数据结构首先,我们需要创建一个图的数据结构,以方便后续的操作。

图可以使用邻接矩阵或邻接表来表示,这里我们选择使用邻接矩阵。

class Graph:def__init__(self, num_vertices):self.num_vertices = num_verticesself.adj_matrix = [[0] * num_vertices for _ in range(num_vertic es)]def add_edge(self, v1, v2):self.adj_matrix[v1][v2] =1self.adj_matrix[v2][v1] =1def get_adjacent_vertices(self, v):adjacent_vertices = []for i in range(self.num_vertices):if self.adj_matrix[v][i] ==1:adjacent_vertices.append(i)return adjacent_vertices2. 深度优先搜索(DFS)DFS是一种遍历图的算法,其基本思想是从图的某一顶点开始,沿着一条路径一直走到最后,然后返回尚未访问过的顶点继续遍历,直到所有顶点都被访问过为止。

def dfs(graph, start_vertex):visited = [False] * graph.num_verticesstack = [start_vertex]while stack:vertex = stack.pop()if not visited[vertex]:print(vertex)visited[vertex] =Truefor neighbor in graph.get_adjacent_vertices(vertex):if not visited[neighbor]:stack.append(neighbor)3. 广度优先搜索(BFS)BFS同样是一种遍历图的算法,其基本思想是从图的某一顶点开始,首先访问其所有邻接点,然后再依次访问邻接点的邻接点,直到所有顶点都被访问过为止。

图的遍历及生成树

图的遍历及生成树

• •邻接表的DFS算法
void DFS(ALGraph G, int v) { ArcNode *p;
visited[v] = 1; /*置已访问标记*/ printf("%d ", v); /*输出被访问顶点的编号*/ p = G.vertices[v].firstarc; /*p指向顶点v的第一个邻接点*/ while (p!=NULL) {
•v11
•v1,
•v2
•v3
•v2,
•v4,
•v5
•v8,
•v4
•v6
•v7
•v5,
•v3,
•v8
•v6,
•v7

•图的DFS算法一般描述
•int visited[MAXVEX]; //访问标志数组
•void DFSTraverse(Graph G)
•{ //对图G作深度优先遍历
• for( v=0; v<G.vexnum; ++v ) visited[v]=FALSE;
•} // DFS1
•G.arcs[v][j] =1
•有邻接点
•visited [n]=0
•未访问过

分析:
在遍历图时,对图中每个顶点至多调用一次DFS函数 ,因为一旦某个顶点被标志成已被访问,就不再从它出发 进行搜索。
因此,遍历图的过程实质上是对每个顶点查找其邻接 点的过程。其耗费的时间则取决于所采用的存储结构。 如果用邻接矩阵来表示图,遍历图中每一个顶点都要从 头扫描该顶点所在行,因此遍历全部顶点所需的时间为 O(n2)。 如果用邻接表来表示图,虽然有 2e 个表结点,但只需扫 描 e 个结点即可完成遍历,加上访问 n个头结点的时间, 因此遍历图的时间复杂度为O(n+e)。

图的遍历操作实验报告

图的遍历操作实验报告

-实验三、图的遍历操作一、目的掌握有向图和无向图的概念;掌握邻接矩阵和邻接链表建立图的存储构造;掌握DFS及BFS对图的遍历操作;了解图构造在人工智能、工程等领域的广泛应用。

二、要求采用邻接矩阵和邻接链表作为图的存储构造,完成有向图和无向图的DFS 和BFS操作。

三、DFS和BFS 的根本思想深度优先搜索法DFS的根本思想:从图G中*个顶点Vo出发,首先访问Vo,然后选择一个与Vo相邻且没被访问过的顶点Vi访问,再从Vi出发选择一个与Vi相邻且没被访问过的顶点Vj访问,……依次继续。

如果当前被访问过的顶点的所有邻接顶点都已被访问,则回退到已被访问的顶点序列中最后一个拥有未被访问的相邻顶点的顶点W,从W出发按同样方法向前遍历。

直到图中所有的顶点都被访问。

广度优先算法BFS的根本思想:从图G中*个顶点Vo出发,首先访问Vo,然后访问与Vo相邻的所有未被访问过的顶点V1,V2,……,Vt;再依次访问与V1,V2,……,Vt相邻的起且未被访问过的的所有顶点。

如此继续,直到访问完图中的所有顶点。

四、例如程序1.邻接矩阵作为存储构造的程序例如#include"stdio.h"#include"stdlib.h"#define Ma*Verte*Num 100 //定义最大顶点数typedef struct{char ve*s[Ma*Verte*Num]; //顶点表int edges[Ma*Verte*Num][Ma*Verte*Num]; //邻接矩阵,可看作边表int n,e; //图中的顶点数n和边数e}MGraph; //用邻接矩阵表示的图的类型//=========建立邻接矩阵=======void CreatMGraph(MGraph *G){int i,j,k;char a;printf("Input Verte*Num(n) and EdgesNum(e): ");scanf("%d,%d",&G->n,&G->e); //输入顶点数和边数scanf("%c",&a);printf("Input Verte* string:");for(i=0;i<G->n;i++){scanf("%c",&a);G->ve*s[i]=a; //读入顶点信息,建立顶点表}for(i=0;i<G->n;i++)for(j=0;j<G->n;j++)G->edges[i][j]=0; //初始化邻接矩阵printf("Input edges,Creat Adjacency Matri*\n");for(k=0;k<G->e;k++) { //读入e条边,建立邻接矩阵 scanf("%d%d",&i,&j); //输入边〔Vi,Vj〕的顶点序号G->edges[i][j]=1;G->edges[j][i]=1; //假设为无向图,矩阵为对称矩阵;假设建立有向图,去掉该条语句}}//=========定义标志向量,为全局变量=======typedef enum{FALSE,TRUE} Boolean;Boolean visited[Ma*Verte*Num];//========DFS:深度优先遍历的递归算法======void DFSM(MGraph *G,int i){ //以Vi为出发点对邻接矩阵表示的图G进展DFS搜索,邻接矩阵是0,1矩阵 int j;printf("%c",G->ve*s[i]); //访问顶点Vivisited[i]=TRUE; //置已访问标志for(j=0;j<G->n;j++) //依次搜索Vi的邻接点if(G->edges[i][j]==1 && ! visited[j])DFSM(G,j); //〔Vi,Vj〕∈E,且Vj未访问过,故Vj为新出发点}void DFS(MGraph *G){int i;for(i=0;i<G->n;i++)visited[i]=FALSE; //标志向量初始化for(i=0;i<G->n;i++)if(!visited[i]) //Vi未访问过DFSM(G,i); //以Vi为源点开场DFS搜索}//===========BFS:广度优先遍历=======void BFS(MGraph *G,int k){ //以Vk为源点对用邻接矩阵表示的图G进展广度优先搜索 int i,j,f=0,r=0;int cq[Ma*Verte*Num]; //定义队列for(i=0;i<G->n;i++)visited[i]=FALSE; //标志向量初始化for(i=0;i<G->n;i++)cq[i]=-1; //队列初始化printf("%c",G->ve*s[k]); //访问源点Vkvisited[k]=TRUE;cq[r]=k; //Vk已访问,将其入队。

图的遍历的实验报告

图的遍历的实验报告

图的遍历的实验报告图的遍历的实验报告一、引言图是一种常见的数据结构,它由一组节点和连接这些节点的边组成。

图的遍历是指从图中的某个节点出发,按照一定的规则依次访问图中的所有节点。

图的遍历在许多实际问题中都有广泛的应用,例如社交网络分析、路线规划等。

本实验旨在通过实际操作,深入理解图的遍历算法的原理和应用。

二、实验目的1. 掌握图的遍历算法的基本原理;2. 实现图的深度优先搜索(DFS)和广度优先搜索(BFS)算法;3. 比较并分析DFS和BFS算法的时间复杂度和空间复杂度。

三、实验过程1. 实验环境本实验使用Python编程语言进行实验,使用了networkx库来构建和操作图。

2. 实验步骤(1)首先,我们使用networkx库创建一个包含10个节点的无向图,并添加边以建立节点之间的连接关系。

(2)接下来,我们实现深度优先搜索算法。

深度优先搜索从起始节点开始,依次访问与当前节点相邻的未访问过的节点,直到遍历完所有节点或无法继续访问为止。

(3)然后,我们实现广度优先搜索算法。

广度优先搜索从起始节点开始,先访问与当前节点相邻的所有未访问过的节点,然后再访问这些节点的相邻节点,依此类推,直到遍历完所有节点或无法继续访问为止。

(4)最后,我们比较并分析DFS和BFS算法的时间复杂度和空间复杂度。

四、实验结果经过实验,我们得到了如下结果:(1)DFS算法的时间复杂度为O(V+E),空间复杂度为O(V)。

(2)BFS算法的时间复杂度为O(V+E),空间复杂度为O(V)。

其中,V表示图中的节点数,E表示图中的边数。

五、实验分析通过对DFS和BFS算法的实验结果进行分析,我们可以得出以下结论:(1)DFS算法和BFS算法的时间复杂度都是线性的,与图中的节点数和边数呈正比关系。

(2)DFS算法和BFS算法的空间复杂度也都是线性的,与图中的节点数呈正比关系。

但是,DFS算法的空间复杂度比BFS算法小,因为DFS算法只需要保存当前路径上的节点,而BFS算法需要保存所有已访问过的节点。

图的遍历实验报告

图的遍历实验报告

1.问题描述:不少涉及图上操作的算法都是以图的遍历操作为基础的。

试写一个程序,演示在连通的无向图上访问全部结点的操作。

2.基本要求:以邻接表为存储结构,实现连通无向图的深度优先和广度优先遍历。

以用户指定的结点为起点,分别输出每种遍历下的结点访问序列和相应生成树的边集。

3.测试数据:教科书图7.33。

暂时忽略里程,起点为北京。

4.实现提示:设图的结点不超过30个,每一个结点用一个编号表示(如果一个图有n个结点,则它们的编号分别为1,2,…,n)。

通过输入图的全部边输入一个图,每一个边为一个数对,可以对边的输入顺序作出某种限制,注意,生成树的边是有向边,端点顺序不能颠倒。

5.选作内容:(1) .借助于栈类型(自己定义和实现),用非递归算法实现深度优先遍历。

(2) .以邻接表为存储结构,建立深度优先生成树和广度优先生成树,再按凹入表或者树形打印生成树。

1.为实现上述功能,需要有一个图的抽象数据类型。

该抽象数据类型的定义为:ADT Graph{V 是具有相同特性的数据元素的集合,称为顶点集。

R={VR}VR={<v,w> | v ,w v 且P(v,w),<v,w>表示从v 到w 得弧,谓词P(v,w)定义了弧<v,w>的意义或者信息}} ADT Graph2.此抽象数据类型中的一些常量如下:#define TRUE 1#define FALSE 0#define OK 1#define max_n 20 //最大顶点数typedef char VertexType[20];typedef enum{DG, DN, AG, AN} GraphKind;enum BOOL{False,True};3.树的结构体类型如下所示:typedef struct{ //弧结点与矩阵的类型int adj; //VRType为弧的类型。

图--0,1;网--权值int *Info; //与弧相关的信息的指针,可省略}ArcCell, AdjMatrix[max_n][max_n];typedef struct{VertexType vexs[max_n]; //顶点AdjMatrix arcs; //邻接矩阵int vexnum, arcnum; //顶点数,边数}MGraph;//队列的类型定义typedef int QElemType;typedef struct QNode{QElemType data;struct QNode *next;}QNode, *QueuePtr;typedef struct{QueuePtr front;QueuePtr rear;}LinkQueue;4.本程序包含三个模块1).主程序模块void main( ){创建树;深度优先搜索遍历;广度优先搜索遍历;}2).树模块——实现树的抽象数据类型3).遍历模块——实现树的深度优先遍历和广度优先遍历各模块之间的调用关系如下:主程序模块树模块遍历模块#include "stdafx.h"#include<iostream>using namespace std;#define TRUE 1#define FALSE 0#define OK 1#define max_n 20 //最大顶点数typedef char VertexType[20];typedef enum{DG, DN, AG, AN} GraphKind;enum BOOL{False,True};typedef struct{ //弧结点与矩阵的类型int adj; //VRType为弧的类型。

图遍历算法

图遍历算法

图遍历算法图遍历算法是一种基于图的搜索算法,用于从图中搜索指定的节点或路径。

图在计算机科学中是一种重要的数据结构,它可以用来表示一组复杂的关系。

图中的每个节点都是一个对象,而边则用来表示两个节点之间的关系。

图遍历算法类似于树遍历算法,其主要目的是从图中寻找某一节点或指定的路径。

图遍历算法的基本操作步骤1.图中的所有节点标记为未访问状态。

2. 从起始节点开始遍历,将当前节点标记为已访问状态。

3.查当前节点是否是目标节点,如果是则结束遍历,否则继续遍历。

4.查当前节点的相邻节点,如果有未访问的节点,则将其标记为已访问,并将其加入到待访问队列中。

5.复步骤3和步骤4,直到找到目标节点或遍历完整个图。

图遍历算法的应用场景图遍历算法主要用于图的搜索和路径查找。

它的应用场景有: 1.路算法:主要应用于地图导航、交通管理、机器人导航等场景,用于查找从指定的节点A到终点B的最优路径。

2.短路径算法:主要用于网络及其他复杂系统中,查找从起始节点到终点之间最短路径,也就是说,需要查找距离最短的路径,而不是按照一定顺序查找路径。

3.联分析算法:它是一种数据挖掘技术,用于挖掘分析大规模数据集合中被关联的结构和模式,包括聚类分析、关系挖掘、推荐系统等。

图遍历算法可以用于查找关联的数据,从而发现有益的模式和网络结构。

4.像处理:图像处理系统中,常常会使用图遍历算法来获取图像的各种特征,例如:特征提取、边缘检测、物体检测和分割等。

图遍历算法的性能图遍历算法的性能可以用时间复杂度和空间复杂度来表示,一般来说,图遍历算法的时间复杂度为 O(V+E)其中 V 为图中的节点数,E 为边的数目。

对于空间复杂度,一般会使用一个队列来保存待访问的节点,空间复杂度为 O(V) 。

总结图遍历算法是一种基于图的搜索算法,它主要用于搜索指定的节点或路径,并用于诸如寻路算法、最短路径算法、关联分析算法和图像处理等不同场景。

图遍历算法的时间复杂度为 O(V+E),空间复杂度为 O(V)因此,它适合于处理大型图,而不适用于小规模的图。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

#define INFINITY 10000 /*无穷大*/#define MAX_VERTEX_NUM 40#define MAX 40#include<stdlib.h>#include<stdio.h>#include<conio.h>#include<string.h>typedef struct ArCell{int adj;}ArCell,AdjMatrix[MAX_VERTEX_NUM][MAX_VERTEX_NUM]; typedef struct{char name[20];}infotype;typedef struct{infotype vexs[MAX_VERTEX_NUM];AdjMatrix arcs;int vexnum,arcnum;}MGraph;int LocateVex(MGraph *G,char* v){ int c=-1,i;for(i=0;i<G->vexnum;i++)if(strcmp(v,G->vexs[i].name)==0){c=i;break;}return c;}MGraph * CreatUDN(MGraph *G)//初始化图,接受用户输入{int i,j,k,w;char v1[20],v2[20];printf("请输入图的顶点数,弧数:");scanf("%d%d",&G->vexnum,&G->arcnum);printf("结点名字:\n");for(i=0;i<G->vexnum;i++){printf("No.%d:",i+1);scanf("%s",G->vexs[i].name);}for(i=0;i<G->vexnum;i++)for(j=0;j<G->vexnum;j++)G->arcs[i][j].adj=INFINITY;printf("请输入一条边依附的两个顶点和权值:\n");for(k=0;k<G->arcnum;k++){printf("第%d条边:\n",k+1);printf("起始结点:");scanf("%s",v1);printf("结束结点:");scanf("%s",v2);printf("边的权值:");scanf("%d",&w);i=LocateVex(G,v1);j=LocateVex(G,v2);if(i>=0&&j>=0){G->arcs[i][j].adj=w;G->arcs[j][i]=G->arcs[i][j];}}return G;}int FirstAdjVex(MGraph *G,int v){int i;if(v<=0 &&v<G->vexnum){ //v合理for(i=0;i<G->vexnum;i++)if(G->arcs[v][i].adj!=INFINITY)return i;}return -1;}void VisitFunc(MGraph *G,int v){printf("%s ",G->vexs[v].name);}int NextAdjVex(MGraph *G,int v,int w){int k;if(v>=0 && v<G->vexnum && w>=0 && w<G->vexnum)//v,w合理{for( k=w+1;k<G->vexnum;k++)if(G->arcs[v][k].adj!=INFINITY)return k;}return -1;}int visited[MAX];void DFS(MGraph *G,int v)//从第v个顶点出发递归地深度优先遍历图Gint w;visited[v]=1;VisitFunc(G,v);//访问第v个结点for(w=FirstAdjVex(G,v);w>=0;w=NextAdjVex(G,v,w)) if(!visited[w]){DFS(G,w);printf("%d ",G->arcs[v][w].adj);}}void DFSTraverse(MGraph *G,char *s)//深度优先遍历{int v,k;for(v=0;v<G->vexnum;v++)visited[v]=0;k=LocateVex(G,s);if(k>=0&&k<G->vexnum){for(v=k;v>=0;v--){if(!visited[v])DFS(G,v);}for(v=k+1;v<G->vexnum;v++)if(!visited[v])DFS(G,v);}}typedef struct Qnode{int vexnum;struct Qnode *next;}QNode,*QueuePtr;typedef struct{QueuePtr front;QueuePtr rear;}LinkQueue;int InitQueue(LinkQueue *Q){Q->front=Q->rear=(QueuePtr)malloc(sizeof(QNode)); if(!Q->front)exit(0);Q->front->next=NULL;return 1;}void EnQueue(LinkQueue *Q,int a )QueuePtr p;p=(QueuePtr)malloc(sizeof(QNode));if(!p)exit(0);p->vexnum=a;p->next=NULL;Q->rear->next=p;Q->rear=p;}int DeQueue(LinkQueue *Q,int *v){ QueuePtr p;if(Q->front==Q->rear){printf("结点不存在!\n");exit(0);}p=Q->front->next;*v=p->vexnum;Q->front->next=p->next;if(Q->rear==p)Q->front=Q->rear;return *v;}int QueueEmpty(LinkQueue *Q){if(Q->rear==Q->front)return 0;return 1;}int Visited[MAX];void BFSTraverse(MGraph *G,char *str)//广度优先遍历{int w,u,v,k;LinkQueue Q,q;for(v=0;v<G->vexnum;v++) Visited[v]=0;InitQueue(&Q);InitQueue(&q);k=LocateVex(G,str);for(v=k;v>=0;v--)if(!Visited[v]){Visited[v]=1;VisitFunc(G,v);EnQueue(&Q,v);//v入队while(!QueueEmpty(&Q)){DeQueue(&Q,&u);//出队for(w=FirstAdjVex(G,u);w>=0;w=NextAdjVex(G,u,w))if(!Visited[w]){Visited[w]=1;VisitFunc(G,v);EnQueue(&Q,w);}}}for(v=k+1;v<G->vexnum;v++)if(!Visited[v]){Visited[v]=1;VisitFunc(G,v);EnQueue(&Q,v);//v入队while(!QueueEmpty(&Q)){DeQueue(&Q,&u);//出队for(w=FirstAdjVex(G,u);w>=0;w=NextAdjVex(G,u,w))if(!Visited[w]){Visited[w]=1;VisitFunc(G,v);EnQueue(&Q,w);}}}}void main(){MGraph *G,b;char v[10];G=CreatUDN(&b);printf("请输入起始结点名称:");scanf("%s",v);printf("\n深度优先遍历:\n");DFSTraverse(G,v);printf("\n广度优先遍历:\n");BFSTraverse(G,v);getch();}/****************** queue.h ***********************/ /**//***************描述队列*******************************/#ifndef QUEUE_H#define QUEUE_H#include <stdio.h>#include <iostream>using namespace std ;typedef struct QNode...{int data ;struct QNode * next ;}QNode ;typedef struct Queue...{QNode * front ;QNode * rear ;}Queue ;void InitQueue(Queue & q)//初始化队列...{q.front = q.rear = new QNode ;q.front->next = q.rear->next = NULL ;}void DestroyQueue(Queue & q)//销毁队列...{while(q.front != NULL)...{q.rear = q.front->next ;delete q.front ;q.front = q.rear ;}}void EnQueue(Queue & q , int data)//队尾插入元素...{QNode * p = new QNode ;p->data = data ;p->next = NULL ;q.rear->next = p ;q.rear = p ;}void DeQueue(Queue & q) //队首删除元素...{if (q.rear == q.front) return ; //队列为空,返回QNode * p = q.front->next ;q.front->next = p->next ;if(p == q.rear)...{q.rear = q.front ;}delete p ;}int GetFront(Queue q) //返回队首元素...{return q.front->next->data ;}int QueueEmpty(Queue q) //如果队列为空,返回0 ; 否则返回1...{if(q.front->next == NULL)return 0 ;elsereturn 1 ;}#endif/**//************************main.cpp*******************************/#include "queue.h"#include <stdio.h>#include <iostream>using namespace std ;//建立存储边的结构typedef struct Edge...{int vertex1 ;int vertex2 ;struct Edge * next ;} Edge ;typedef struct Node...{int vertex ;struct Node * next ;}Node ;typedef Edge * ListEdge ;typedef Node * AdjList ;void CreateListEdge(ListEdge & LE ,int& N);//将边的信息用链表存储起来void CreateGraph(ListEdge LE , int N , int **&Graph);//根据边的信息,建立邻接矩阵void CreateAdjList(AdjList *& AL,int ** Graph,int N);//根据邻接矩阵,创建邻接表void DFS(int vertex,int N,AdjList * AL,int *& visit);//利用邻接表,深度优先遍历图,采用递归算法void BFS(int vertex,int n,AdjList * AL,int *& visit); //利用邻接表,广度优先遍历图int main()...{ListEdge LE = NULL;int ** Graph ;AdjList * AL = NULL ;int * visit ;int i = 0 ;int n = 0 ;CreateListEdge(LE,n);cout<<"邻接矩阵:"<<endl;CreateGraph(LE,n,Graph);cout<<"邻接表:"<<endl;CreateAdjList(AL,Graph,n);//对所有的节点开始先深遍历,并且打印出来cout<<"深度优先搜索: "<<endl ;visit = new int[n] ;for(i = 0 ; i < n ; i++)...{for(int j = 0 ; j < n ; j++)...{visit[j] = 0 ;}DFS(i , n , AL,visit);cout<<"end"<<endl ;}cout<<"广度优先搜索: "<<endl ;for(i = 0 ; i < n ; i++)...{for(int j = 0 ; j < n ; j++)...{visit[j] = 0 ;}BFS(i , n , AL,visit);}system("PAUSE");return 0 ;}void CreateListEdge(ListEdge & LE,int &N)//将边的信息用链表存储起来...{LE = new Edge ;ListEdge s ;ListEdge r = LE;N = 0 ;int i = 0 ;int j = 0 ;//处理输入while(cin>>i)...{if(i != 0)...{cin>>j ;int temp ;if(i >=j)...{temp = i ;}else...{temp = j ;}if(temp >= N)...{N = temp ;}s = new Edge ;s->vertex1 = i ;s->vertex2 = j ;s->next = NULL ;r->next = s ;r = s ;}else...{r->next = NULL ;break ;}}//输出链表的内容验证/**//*ListEdge l = LE->next ;putchar(' ');while(l != NULL){cout<<l->vertex1<<" "<<l->vertex2<<endl ;l = l ->next ;}*/}void CreateGraph(ListEdge LE , int N , int **&Graph)//根据边的信息,建立邻接矩阵...{int i = 0 ;int j = 0 ;//动态建立图Graph = new int *[N] ;for(i = 0 ; i < N ; i++)...{Graph = new int[N] ;}for(i = 0 ; i < N ; i++)...{for(j = 0 ; j < N ; j++)...{Graph[j] = 0 ;}}ListEdge l = LE->next ;while(l != NULL)...{Graph[l->vertex1-1][l->vertex2-1] = 1 ;Graph[l->vertex2-1][l->vertex1-1] = 1 ;l = l->next ;}//输出邻接矩阵的内容,对照图形进行验证printf(" ");for(i = 0 ; i < N ; i++)...{printf("%3d",i+1);}putchar(' ');for(i = 0 ; i < N ; i++)...{printf("%4d ",i+1);for(j = 0 ; j < N ; j++)...{printf("%3d",Graph[j]);//cout<<" "<<Graph[j]<<" ";}putchar(' ');}}void CreateAdjList(AdjList * &AL,int ** Graph,int N)//根据邻接矩阵,创建邻接表...{AL = new AdjList[N];int i = 0 ;int j = 0 ;for(i = 0 ; i < N ; i++)//初始化...{AL = new Node ;AL->next = NULL ;}for(i = 0 ; i < N ; i++)...{for(j = 0 ; j < N ; j++)...{if(Graph[j] != 0)//如果端点相连,建立邻接表...{AdjList p = new Node ;p->vertex = j ;p->next = AL->next ;AL->next = p ;}}}//打印邻接表for(i = 0 ; i < N ; i++)...{AdjList p = AL->next ;cout<<"节点"<<i+1<<": ";while(p != NULL)...{cout<<p->vertex + 1<<" ";p = p->next ;}putchar(' ');}}void DFS(int vertex,int N,AdjList * AL,int *& visit)//利用邻接表,深度优先遍历图...{visit[vertex] = 1 ;cout<<vertex + 1<<"-->";Node * p = AL[vertex]->next ;while(p != NULL)...{if(visit[p->vertex] == 0) //还没有被访问...{DFS(p->vertex,N,AL,visit);}p = p ->next ;}}void BFS(int vertex,int n,AdjList * AL,int *& visit)//利用邻接表,广度优先遍历图...{int temp = 0 ;Queue q ;InitQueue(q);EnQueue(q,vertex + 1);//存入选择的顶点标号visit[vertex] = 1 ;//设置已经访问while(QueueEmpty(q) != 0) //队列为空,先广搜索完毕...{temp = GetFront(q); //取出队列首节点cout<<temp<<"-->"; //打印DeQueue(q);//从队列首部删除AdjList p = AL[temp - 1]->next ;while(p != NULL)//把队首节点的邻接点(没有访问的)进队,并设置已经访问...{if(0 == visit[p->vertex])...{EnQueue(q,p->vertex + 1) ;visit[p->vertex] = 1 ;}p = p->next ;}}cout<<"end"<<endl ;DestroyQueue(q);}、#include <iostream>using namespace std;#define MAXNODE 64 // 图中顶点的最大个数typedef char vertype;struct ArcNode // 弧(边)结点:{int adjvex; // 邻接点在顶点向量中的下标ArcNode *next; // 指向下一邻接点的指针};struct VerNode // 顶点结点:{vertype vertex; // 顶点信息ArcNode *firstarc; // 指向第一个邻接点的指针};struct AlGraph// 邻接表:{VerNode vertices[MAXNODE];int vernum; //顶点的数目int arcnum; // 边的数目};struct Queue//队列{int elem;Queue *next;};void QueueInit(Queue &Q){Q.next=NULL;}void QueueIn(Queue &Q,int &v){Queue *p=&Q;while(p->next){p=p->next;}Queue *temp=new Queue;temp->elem=v;temp->next=p->next;p->next=temp;}bool QueueEmpty(Queue &Q){if(Q.next)return true;elsereturn false;}void QueueOut(Queue &Q,int &v){Queue *temp;temp=Q.next;v=temp->elem;Q.next=temp->next;delete temp;}int GraphLocateVertex(AlGraph &G,int v){return v-1;}void CreateAdjList(AlGraph &G)//此图为有向图{int n;cout<<"请输入顶点数目"<<endl;cin>>n;G.vernum=n;//顶点初始化为nG.arcnum=0;//边数初始化为0cout<<"请输入各个顶点的数据"<<endl;for(int i=0;i<n;i++){cin>>G.vertices[i].vertex;//输入顶点信息G.vertices[i].firstarc=NULL;}cout<<"请输入有联系的两顶点:输入方式如:第一个点和第二个点输入成:1 2"<<endl; int v1,v2;cin>>v1>>v2;int i,j;ArcNode *p=NULL;while(v1&&v2)//两顶点同时为0时结束{i=GraphLocateVertex(G,v1);j=GraphLocateVertex(G,v2);p=new ArcNode();p->adjvex=j;p->next=G.vertices[i].firstarc;G.vertices[i].firstarc=p;G.arcnum++;//边数加1cin>>v1>>v2;}}int visited[MAXNODE];//访问标志数组void visit(AlGraph &G,int v){cout<<G.vertices[v].vertex<<" ";}//以下为深度优先遍历DFSint GraphFirstAdj(AlGraph &G,int v){if(G.vertices[v].firstarc)return G.vertices[v].firstarc->adjvex;return -1;}int GraphNextAdj(AlGraph &G,int v,int w){ArcNode *p=G.vertices[v].firstarc;while(p->adjvex!=w){p=p->next;}p=p->next;if(p)return p->adjvex;elsereturn -1;}void DFS(AlGraph &G,int v){//从第v个顶点出发递归地深度优先遍历图Gvisited[v]=1; visit(G,v);//访问v顶点并将该顶点设为已访问for(int w=GraphFirstAdj(G,v);w!=-1;w=GraphNextAdj(G,v,w))//-1退出{if(!visited[w])DFS(G,w);//对v的上文访问的邻接顶点w递归调用}}void DFSTraverse(AlGraph &G){for(int v=0;v<G.vernum;v++)//访问数组初始化visited[v]=0;for(int v=0;v<G.vernum;v++){if(!visited[v])DFS(G,v);//对未访问的顶点调用DFS}//以下为广度优先遍历BFSvoid BFSTraverse(AlGraph &G){//广度优先遍历for(int v=0;v<G.vernum;v++)visited[v]=0;Queue Q;QueueInit(Q);//辅助队列Qfor(int v=0;v<G.vernum;v++)if(!visited[v]){QueueIn(Q,v);visited[v]=1;visit(G,v);int u;while(!QueueEmpty(Q)){QueueOut(Q,u);//对头元素出队列并置为ufor(int w=GraphFirstAdj(G,u);w!=-1;w=GraphNextAdj(G,u,w)) {if(!visited[w]){QueueIn(Q,w);//u的尚未访问的邻接顶点w入队列Qvisited[w]=1;visit(G,w);}}}}}int main(){AlGraph G;CreateAdjList(G);DFSTraverse(G);cout<<endl;BFSTraverse(G);cout<<endl;cout<<G.vernum<<" "<<G.arcnum<<endl;cout<<endl;return 0;#include<stdio.h>#include<stdlib.h>#include<limits.h>#define MaxVertexNum 100#define True 1#define False 0#define OVERFLOW -1#define OK 1#define ERROR 0typedef int Status;typedef int boolean;typedef char VertexType;typedef int EdgeType;//邻接矩阵的定义typedef struct MGraphNode{VertexType vexs[MaxVertexNum];EdgeType edges[MaxVertexNum][MaxVertexNum];int n,e;}*MGraph;//用邻接矩阵构造带权值有向图void CreateMGraph(MGraph &G){int i,j,k,w;char ch;G=(MGraph)malloc(sizeof(MGraphNode));printf("输入顶点数和边数,以空格隔开\n");scanf("%d%d",&(G->n),&(G->e));printf("请输入顶点信息,以空格分开:\n");i=0;while(i<G->n){ch=getchar();if(ch!=' '&&ch!='\n')G->vexs[i++]=ch;}printf("%c \n",G->vexs[0]);for(i=0;i<G->n;i++)for(j=0;j<G->n;j++)G->edges[i][j]=INT_MAX;printf("请输入弧的信息,格式为:弧尾弧头权值:\n"); for(k=0;k<G->e;k++){scanf("%d%d%d",&i,&j,&w);G->edges[i][j]=w;}}//邻接矩阵图的深度优先遍历boolean visited[MaxVertexNum];int FirstAdjVex(MGraph G,int v){int w;for(w=0;w<G->n;w++)if(G->edges[v][w]!=INT_MAX)return w;return -1;}int NextAdjVex(MGraph G,int v,int w){int w2;for(w2=w+1;w2<G->n;w2++)if(G->edges[v][w2]!=INT_MAX)return w2;return -1;}void DFSMG(MGraph G,int v){visited[v]=True;int w;printf("%c ",G->vexs[v]);for(w=FirstAdjVex(G,v);w>0;w=NextAdjVex(G,v,w)) if(!visited[w])DFSMG(G,w);}void DFSTraverseMG(MGraph G){printf("图的深度优先遍历:");int i;for(i=0;i<G->n;i++)visited[i]=False;for(i=0;i<G->n;i++)if(!visited[i])DFSMG(G,i);putchar('\n');}//邻接矩阵图的广度优先遍历,要借助于队列//首先定义和创建队列typedef struct SqQueue{int *base;int head,tail;}SqQueue;//构建队列Status InitQueue(SqQueue &Q){Q.base=(int*)malloc(sizeof(int)*MaxVertexNum); if(!Q.base)return OVERFLOW;Q.head=Q.tail=0;return OK;}//判断队列是否为空boolean QueueEmpty(SqQueue Q){return Q.tail==Q.head;}//入队操作Status EnQueue(SqQueue &Q,int e){if(Q.tail==Q.head)return ERROR;//队列满不能入Q.base[Q.tail]=e;Q.tail=(Q.tail+1)%MaxVertexNum;return OK;}//出队操作Status DeQueue(SqQueue &Q,int &e){if(QueueEmpty(Q))return ERROR;//队空不能出队e=Q.base[Q.head];Q.head=(Q.head+1)%MaxVertexNum;return OK;}//BFSMG()函数供BFSTraverseMG()函数调用void BFSMG(MGraph G,int v){int i,j;SqQueue Q;InitQueue(Q);visited[v]=True;printf("%c ",G->vexs[v]);EnQueue(Q,v);while(!QueueEmpty(Q)){DeQueue(Q,i);for(j=0;j<G->n;j++)if(G->edges[i][j]!=INT_MAX&&!visited[j]){ printf("%c ",G->vexs[j]);visited[j]=True;EnQueue(Q,j);}}}void BFSTraverseMG(MGraph G){printf("图的广度优先遍历:");int i;for(i=0;i<G->n;i++)visited[i]=False;for(i=0;i<G->n;i++)if(!visited[i])BFSMG(G,i); putchar('\n');}//主函数int main(){MGraph MG;CreateMGraph(MG);DFSTraverseMG(MG);BFSTraverseMG(MG);system("pause");return 0;}。

相关文档
最新文档