图的深度优先遍历实验报告.doc

合集下载

图论深度优先搜索实验报告

图论深度优先搜索实验报告

深度优先遍历一、实验目的了解深度优先遍历的基本概念以及实现方式。

二、实验内容1、设计一个算法来对图的进行深度优先遍历;2、用C语言编程来实现此算法。

用下面的实例来调试程序:三、使用环境Xcode编译器四、编程思路深度优先遍历图的方法是,从邻接矩阵出发:访问顶点v;依次从v的未被访问的邻接点出发,对图进行深度优先遍历;直至图中和v有路径相通的顶点都被访问;构造一个遍历辅助矩阵visited[]进行比较若此时图中尚有顶点未被访问,则从一个未被访问的顶点出发,重新进行深度优先遍历,直到图中所有顶点均被访问过为止,并将顶点信息存储在数组Q[]里面。

反复搜索可以通过使用函数的嵌套来实现。

五、调试过程1.程序代码://为方便调试,程序清晰直观删除了邻接矩阵的构造函数,//并且修改了main()函数,只保留了DFS函数#include <stdio.h>#define N 4 //定义顶点数int a[N][N]={{0,1,1,1},{1,0,0,0},{1,0,0,1},{1,0,0,1}}; //邻接矩阵由之前程序函给出int visited[N]={0}; //遍历比较的辅助矩阵,初始化为0矩阵int Q[N]; //用来存储各个顶点的信息static int last=-1;void DFS(int G[][N], int s){visited[s] = 1;Q[++last]=s;for (int i=0;i<N;i++) //进行遍历{if (G[s][i]==1){if(visited[i] == 0)DFS(G,i); //函数嵌套,完成一次搜索,指向下一个顶点 }}}int main(){DFS(a,0);printf("深度优先搜索为\n");for (int i=0;i<N;i++) //打印遍历的结果printf("%d ",Q[i]+1);return 0;}2.运行窗口:输出结果为各顶点按深度优先遍历的排序。

图的遍历 实验报告

图的遍历  实验报告

图的遍历实验报告一、引言图是一种非线性的数据结构,由一组节点(顶点)和节点之间的连线(边)组成。

图的遍历是指按照某种规则依次访问图中的每个节点,以便获取或处理节点中的信息。

图的遍历在计算机科学领域中有着广泛的应用,例如在社交网络中寻找关系紧密的人员,或者在地图中搜索最短路径等。

本实验旨在通过实际操作,掌握图的遍历算法。

在本实验中,我们将实现两种常见的图的遍历算法:深度优先搜索(DFS)和广度优先搜索(BFS),并比较它们的差异和适用场景。

二、实验目的1. 理解和掌握图的遍历算法的原理与实现;2. 比较深度优先搜索和广度优先搜索的差异;3. 掌握图的遍历算法在实际问题中的应用。

三、实验步骤实验材料1. 计算机;2. 编程环境(例如Python、Java等);3. 支持图操作的相关库(如NetworkX)。

实验流程1. 初始化图数据结构,创建节点和边;2. 实现深度优先搜索算法;3. 实现广度优先搜索算法;4. 比较两种算法的时间复杂度和空间复杂度;5. 比较两种算法的遍历顺序和适用场景;6. 在一个具体问题中应用图的遍历算法。

四、实验结果1. 深度优先搜索(DFS)深度优先搜索是一种通过探索图的深度来遍历节点的算法。

具体实现时,我们可以使用递归或栈来实现深度优先搜索。

算法的基本思想是从起始节点开始,选择一个相邻节点进行探索,直到达到最深的节点为止,然后返回上一个节点,再继续探索其他未被访问的节点。

2. 广度优先搜索(BFS)广度优先搜索是一种逐层遍历节点的算法。

具体实现时,我们可以使用队列来实现广度优先搜索。

算法的基本思想是从起始节点开始,依次遍历当前节点的所有相邻节点,并将这些相邻节点加入队列中,然后再依次遍历队列中的节点,直到队列为空。

3. 时间复杂度和空间复杂度深度优先搜索和广度优先搜索的时间复杂度和空间复杂度如下表所示:算法时间复杂度空间复杂度深度优先搜索O(V+E) O(V)广度优先搜索O(V+E) O(V)其中,V表示节点的数量,E表示边的数量。

深度优先搜索实验报告

深度优先搜索实验报告

深度优先搜索实验报告引言深度优先搜索(Depth First Search,DFS)是图论中的一种重要算法,主要用于遍历和搜索图的节点。

在实际应用中,DFS被广泛用于解决迷宫问题、图的连通性问题等,具有较高的实用性和性能。

本实验旨在通过实际编程实现深度优先搜索算法,并通过实际案例验证其正确性和效率。

实验中我们将以迷宫问题为例,使用深度优先搜索算法寻找从入口到出口的路径。

实验过程实验准备在开始实验之前,我们需要准备一些必要的工具和数据。

1. 编程环境:我们选择使用Python语言进行编程实验,因其语法简洁而强大的数据处理能力。

2. 迷宫地图:我们需要设计一个迷宫地图,包含迷宫的入口和出口,以及迷宫的各个路径和墙壁。

实验步骤1. 首先,我们需要将迷宫地图转化为计算机可处理的数据结构。

我们选择使用二维数组表示迷宫地图,其中0表示墙壁,1表示路径。

2. 接着,我们将编写深度优先搜索算法的实现。

在DFS函数中,我们将使用递归的方式遍历迷宫地图的所有路径,直到找到出口或者遇到墙壁。

3. 在每次遍历时,我们将记录已经访问过的路径,以防止重复访问。

4. 当找到出口时,我们将输出找到的路径,并计算路径的长度。

实验结果经过实验,我们成功地实现了深度优先搜索算法,并在迷宫地图上进行了测试。

以下是我们的实验结果:迷宫地图:1 1 1 1 11 0 0 0 11 1 1 0 11 0 0 0 11 1 1 1 1最短路径及长度:(1, 1) -> (1, 2) -> (1, 3) -> (1, 4) -> (2, 4) -> (3, 4) -> (4, 4) -> (5, 4)路径长度:7从实验结果可以看出,深度优先搜索算法能够准确地找到从入口到出口的最短路径,并输出了路径的长度。

实验分析我们通过本实验验证了深度优先搜索算法的正确性和有效性。

然而,深度优先搜索算法也存在一些缺点:1. 只能找到路径的一种解,不能确定是否为最优解。

实现图的遍历算法实验报告

实现图的遍历算法实验报告

实现图的遍历算法实验报告实现图的遍历算法实验报告⼀实验题⽬: 实现图的遍历算法⼆实验要求:2.1:(1)建⽴如图(p126 8.1)所⽰的有向图 G 的邻接矩阵,并输出之(2)由有向图G的邻接矩阵产⽣邻接表,并输出之(3)再由(2)的邻接表产⽣对应的邻接矩阵,并输出之2.2 (1)输出如图8.1所⽰的有向图G从顶点0开始的深度优先遍历序列(递归算法)(2)输出如图8.1所⽰的有向图G从顶点0开始的深度优先遍历序列(⾮递归算法)(3)输出如图8.1所⽰的有向图G从顶点0开始的⼴度优先遍历序列三实验内容:3.1 图的抽象数据类型:ADT Graph{数据对象V:V是具有相同特性的数据元素的集合,称为顶点集。

数据关系R:R={VR}VR={|v,w∈V且P(v,w),表⽰从v到w的弧,谓词P(v,w)定义了弧的意义或信息}基本操作:CreateGraph( &G, V, VR )初始条件:V是图的顶点集,VR是图中弧的集合。

操作结果:按V和VR的定义构造图G。

DestroyGraph( &G )初始条件:图G存在。

操作结果:销毁图G。

LocateVex( G, u )初始条件:图G存在,u和G中顶点有相同特征。

操作结果:若G中存在顶点u,则返回该顶点在图中位置;否则返回其它信息。

GetVex( G, v )初始条件:图G存在,v是G中某个顶点。

操作结果:返回v的值。

PutVex( &G, v, value )初始条件:图G存在,v是G中某个顶点。

初始条件:图G存在,v是G中某个顶点。

操作结果:返回v的第⼀个邻接顶点。

若顶点在G中没有邻接顶点,则返回“空”。

NextAdjVex( G, v, w )初始条件:图G存在,v是G中某个顶点,w是v的邻接顶点。

操作结果:返回v的(相对于w的)下⼀个邻接顶点。

若w是v 的最后⼀个邻接点,则返回“空”。

InsertVex( &G, v )初始条件:图G存在,v和图中顶点有相同特征。

2-深度优先遍历以邻接表存储的图-实验报告

2-深度优先遍历以邻接表存储的图-实验报告

福建江夏学院《数据结构与关系数据库(本科)》实验报告姓名班级学号实验日期课程名称数据结构与关系数据库(本科)指导教师成绩实验名称:深度优先遍历以邻接表存储的图一、实验目的1、掌握以邻接表存储的图的深度优先遍历算法;二、实验环境1、硬件环境:微机2、软件环境:Windows XP,VC6.0三、实验内容、步骤及结果1、实验内容:基于图的深度优先遍历编写一个算法,判别以邻接表方式存储的有向图中是否存在由顶点vi到顶点vj的路径(i≠j)。

2、代码:#include <stdio.h>#include <stdlib.h>#define MaxVertexNum 100 /*最大顶点数为100*/typedef char VertexType;typedef struct node{ /*边表结点*/int adjvex; /*邻接点域*/struct node * next; /*指向下一个邻接点的指针域*//*若要表示边上信息,则应增加一个数据域info*/}EdgeNode;typedef struct vnode{ /*顶点表结点*/VertexType vertex; /*顶点域*/EdgeNode * firstedge; /*边表头指针*/}VertexNode;typedef VertexNode AdjList[MaxVertexNum]; /*AdjList 是邻接表类型*/typedef struct{AdjList adjlist; /*邻接表*/int n,e; /*顶点数和边数*/}ALGraph; /*ALGraph 是以邻接表方式存储的图类型*/bool visited[MaxVertexNum];void CreateALGraph(ALGraph *G){/*建立有向图的邻接表存储*/int i,j,k;EdgeNode * s;printf("请输入顶点数和边数(输入格式为:顶点数,边数):\n");scanf("%d,%d",&(G->n),&(G->e)); /*读入顶点数和边数*/printf("请输入顶点信息(输入格式为:顶点号<CR>):\n");for (i=0;i<G->n;i++) /*建立有n 个顶点的顶点表*/{scanf("\n%c",&(G->adjlist[i].vertex)); /*读入顶点信息*/G->adjlist[i].firstedge=NULL; /*顶点的边表头指针设为空*/}printf("请输入边的信息(输入格式为:i,j):\n");for (k=0;k<G->e;k++) /*建立边表*/{scanf("\n%d,%d",&i,&j); /*读入边<Vi,Vj>的顶点对应序号*/s=(EdgeNode*)malloc(sizeof(EdgeNode)); /*生成新边表结点s*/s->adjvex=j; /*邻接点序号为j*/s->next=G->adjlist[i].firstedge; /*将新边表结点s 插入到顶点Vi 的边表头部*/G->adjlist[i].firstedge=s;}}/*CreateALGraph*/void DFSAL(ALGraph *G,int i){/*以Vi 为出发点对邻接表存储的图G 进行DFS 搜索*/EdgeNode *p;printf("visit vertex:V%c\n",G->adjlist[i].vertex);/*访问顶点Vi*/visited[i]=true; /*标记Vi 已访问*/p=G->adjlist[i].firstedge; /*取Vi 边表的头指针*/while(p) /*依次搜索Vi 的邻接点Vj,j=p->adjva*/{if (!visited[p->adjvex]) /*若Vj 尚未访问,则以Vj 为出发点向纵深搜索*/ DFSAL(G,p->adjvex);p=p->next; /*找Vi 的下一个邻接点*/}}/*DFSAL*/void DFSTraverseAL(ALGraph *G){/*深度优先遍历以邻接表存储的图G*/int i;for (i=0;i<G->n;i++)visited[i]=false; /*标志向量初始化*/for (i=0;i<G->n;i++)if (!visited[i]) DFSAL(G,i); /*vi 未访问过,从vi 开始DFS 搜索*/}/*DFSTraveseAL*/void main(){ALGraph *G;G=(ALGraph *)malloc(sizeof(ALGraph));CreateALGraph(G);printf("深度优先搜索结果:\n");DFSTraverseAL(G);}3、测试数据与实验结果分析(可以用组合键Alt+Print Screen截图):四、心得体会。

图的深度和广度优先遍历

图的深度和广度优先遍历

数据结构课程实验报告课程名称数据结构班级计算123 实验日期2014年6月1日--3日姓名学号实验成绩实验名称实验四图的深度和广度优先遍历实验目的及要求【实验目的】熟练掌握图的邻接表存储结构及其图的建立方法和深度和广度优先遍历的方法。

【实验要求】1.图的存储可采用邻接矩阵或邻接表2.GraphCreate(): 按从键盘的数据建立图3.GraphDFS():深度优先遍历图4.GraphBFS():广度优先遍历图5.编写完整程序完成下面的实验内容并上机运行6.整理并上交实验报告实验环境硬件平台:普通的PC机软件平台:Windows 7 操作系统编程环境:VisualC++ 6.0实验内容1.以邻接矩阵或邻接表为存储结构,以用户指定的顶点为起始点,实现图的深度优先及广度优先搜索遍历,并输出遍历的结点序列。

算法描述及实验步骤算法:1)定义图的邻接表存储结构2)实现图的邻接表存储,即建立图的存储结构3)实现图的深度优先遍历4)定义队列的顺序存储结构,并实现队列的基本操作如初始化队列、入队、出对、判断队列是否为空等。

利用队列实现图的广度优先遍历。

伪代码:1)定义邻接矩阵和队列的存取结构;2)创建图L:1.置空图L->num=0;2.输入顶点数目num;3.i++,输入结点L->vexs[i]直到L->num;3)输出图L的各顶点;4)深度优先遍历图g中能访问的各个顶点1.输入起点的下标qidian;2.标志数组初始化mark[v]=0;3.for(v=qidian;v<g.num+qidian;v++) //{v1=v%g.num;if(mark[v1]==0)DFS(g,v1,mark); //从第v1个点出发深度优先遍历图g中能访问的各个顶点(算法描述里的流程图很详细)}5)广度优先周游图g中能访问的各个顶点。

1.构造空队列;2.入队a[0];3.a[0]出队,a[0]的邻接点入队,遍历a[0];4.队首出队,重复3直到队列为空;5.判断是否全遍历完了;6.输出广度优先遍历序列流程图:开始访问V 0,置标志求V 0邻接点有邻接点w求下一邻接点w V 0W 访问过结束NYN YDFS开始标志数组初始化V i =1Vi 访问过DFSV i =V i +1V i ==Vexnums结束NNYY调试过程及实验结果总结本次试验采用的是邻接表的方式实现图的深度优先遍历和广度优先遍历。

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

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

数据结构图的遍历实验报告篇一:【数据结构】图的存储和遍历实验报告《数据结构B》实验报告系计算机与电子专业级班姓名学号XX年1 0 月9日1. 上机题目:图的存储和遍历2. 详细设计#include#define GRAPHMAX 10#define FALSE 0#define TRUE 1#define error printf#define QueueSize 30typedef struct{char vexs[GRAPHMAX];int edges[GRAPHMAX][GRAPHMAX];int n,e;}MGraph;int visited[10];typedef struct{int front,rear,count;int data[QueueSize];}CirQueue;void InitQueue(CirQueue *Q) {Q->front=Q->rear=0;Q->count=0;}int QueueEmpty(CirQueue *Q){return Q->count=QueueSize;}int QueueFull(CirQueue *Q){return Q->count==QueueSize;}void EnQueue(CirQueue *Q,int x) { if(QueueFull(Q)) error("Queue overflow");文档来源为:从网络收集整理.word 版本可编辑.欢迎下载支持else{ Q->count++;Q->data[Q->rear]=x;Q->rear=(Q->rear+1)%QueueSize;}}int DeQueue(CirQueue *Q){int temp;if(QueueEmpty(Q)){ error("Queue underflow");return NULL;}else{ temp=Q->data[Q->front]; Q->count--;Q->front=(Q->front+1)%QueueSize;return temp;}}void CreateMGraph(MGraph *G){int i,j,k;char ch1,ch2;printf("\n\t\t 请输入定点数,边数并按回车 (格式如:3,4):");scanf("%d,%d", &(G->n),&(G->e));for(i=0;in;i++){ getchar();printf("\n\t\t 请输入第%d个定点数并按回车:",i+1);scanf("%c",&(G->vexs[i]));}for(i=0;in;i++)for(j=0;jn;j++)G->edges[i][j]=0;for(k=0;ke;k++){ getchar();printf("\n\t\t 请输入第%d条边的顶点序号 (格式如:i,j ):",k+1);scanf("%c,%c",&ch1,&ch2);for(i=0;ch1!=G->vexs[i];i++);for(j=0;ch2!=G->vexs[j];j++);G->edges[i][j]=1;}}void DFSM(MGraph *G,int i){int j;printf("\n\t\t 深 度 优 列: %c\n",G->vexs[i]);visited[i]=TRUE;for(j=0;jn;j++)if(G->edges[i][j]==1 &&////////////////DFSM(G,j);} void BFSM(MGraph *G,int k){ int i,j;CirQueue Q;InitQueue(&Q);printf("\n\t\t 广 度 优列: %c\n",G->vexs[k]);visited[k]=TRUE;EnQueue(&Q,k); while(!QueueEmpty(&Q)){ i=DeQueue(&Q);先遍历序 visited[j]!=1)先遍历序for(j=0;jn;j++)if(G->edges[i][j]==1 && visited[j]!=1) { visited[j]=TRUE;EnQueue(&Q,j);}}}void DFSTraverseM(MGraph *G) {int i;for(i=0;in;i++)visited[i]=FALSE;for(i=0;in;i++)if(!visited[i]) DFSM(G,i);}void BFSTraverseM(MGraph *G) {int i;for(i=0;in;i++) visited[i]=FALSE;for(i=0;in;i++)if(!visited[i]) BFSM(G,i);}void main(){MGraph *G,a;char ch1;int i,j,ch2;G=&a;printf("\n\t\t 建立一个有向图的邻接矩阵表示\n"); CreateMGraph(G);printf("\n\t\t 已建立一个有向图的邻接矩阵存储\n"); for(i=0;in;i++){ printf("\n\t\t");for(j=0;jn;j++)printf("%5d",G->edges[i][j]);}getchar();ch1='y';while(ch1=='y'||ch1=='Y'){ printf("\n");printf("\n\t\t 图的存储与遍历");("\n\t\t** ******************************");printf("\n\t\t*1 ---- 更新邻接矩阵*"); printf("\n\t\t*2 ---- 深度优先遍历*"); printf("\n\t\t*3 ---- 广度优先遍历*"); printf("\n\t\t*0 ---- 退出*");printf("\n\t\t** ******************************");}} printf("\n\t\t 请选择菜单号 ( 0 ---------------- 3) "); scanf("%d",&ch2); getchar(); switch(ch2) { case1:CreateMGraph(G); printf("\n\t\t 图的邻接矩阵存储建立完成\n");break; case 2:DFSTraverseM(G);break; case3:BFSTraverseM(G);break; case 0:ch1='n';break;default:printf("\n\t\t 输出错误!清重新输入!"); }3. 调试分析(1)调试过程中主要遇到哪些问题?是如何解决的?由于实习之初对邻接表的存储结构了解不是很清楚,所以在运行出了一个小错误,即在输出邻接表时,每个结点都少了一个邻接点。

图的深度和广度遍历-实验报告

图的深度和广度遍历-实验报告

实验报告一、实验目的和内容1. 实验目的掌握图的邻接矩阵的存储结构;实现图的两种遍历:深度优先遍历和广度优先遍历。

2. 实验内容1.图的初始化; 2.图的遍历:深度优先遍历和广度优先遍历。

二、实验方案程序主要代码:/// <summary>/// 邻接矩阵的节点数据/// </summary>public struct ArcCell{public int Type; // 顶点的关系类型,对无权图,用 1或0表示相邻;// 对带权图,则为权值类型。

public object Data; // 该弧相关信息public ArcCell( int type, object data){Type = type;Data = data;}}/// <summary>/// 图的类型/// </summary>public enumGKind {DG,DN,UDG,UDN}; // 有向图,有向网,无向图,无向/// <summary>/// 图类/// </summary>public class Graph{public static int Max_Vertex_Num = 20; // 最大顶点数private object [] Vexs; // 顶点数据数组private ArcCell [,] Arcs; // 邻接矩阵private GKind Kind; // 图的种类private int VexNum,ArcNum; // 当前顶点数和弧数/// <summary>/// 图的初始化方法/// </summary>Ill VParam n ame="vex num">顶点数v∕param>III VParam n ame="arc num">弧数<∕param>Ill VParam name="k">图的类型<∕param> public Graph( int vexnum,int arcnum,GKind k) {VexNum = vexnum;ArcNum = arcnum;Kind = k;Vexs = new object [Max_Vertex_Num];Arcs = newArcCell[Max_Vertex_Num,Max_Vertex_Num];}III Vsummary>III设置v1, v2之间的弧的权值,顶点的关系类型,对无权图,用表示相邻;III 对带权图,则为权值类型。

图的遍历算法实验报告

图的遍历算法实验报告

图的遍历算法实验报告
《图的遍历算法实验报告》
在计算机科学领域,图的遍历算法是一种重要的算法,它用于在图数据结构中
访问每个顶点和边。

图的遍历算法有两种常见的方法:深度优先搜索(DFS)
和广度优先搜索(BFS)。

在本实验中,我们将对这两种算法进行实验,并比较
它们的性能和应用场景。

首先,我们使用深度优先搜索算法对一个简单的无向图进行遍历。

通过实验结
果可以看出,DFS算法会首先访问一个顶点的所有邻居,然后再递归地访问每
个邻居的邻居,直到图中所有的顶点都被访问到。

这种算法在一些应用场景中
非常有效,比如寻找图中的连通分量或者寻找图中的环路。

接下来,我们使用广度优先搜索算法对同样的无向图进行遍历。

通过实验结果
可以看出,BFS算法会首先访问一个顶点的所有邻居,然后再按照距离递增的
顺序访问每个邻居的邻居。

这种算法在一些应用场景中也非常有效,比如寻找
图中的最短路径或者寻找图中的最小生成树。

通过对比实验结果,我们可以发现DFS和BFS算法各自的优势和劣势。

DFS算
法适合用于寻找图中的连通分量和环路,而BFS算法适合用于寻找最短路径和
最小生成树。

因此,在实际应用中,我们需要根据具体的需求来选择合适的算法。

总的来说,图的遍历算法是计算机科学中非常重要的算法之一,它在许多领域
都有着广泛的应用。

通过本次实验,我们对DFS和BFS算法有了更深入的了解,并且对它们的性能和应用场景有了更清晰的认识。

希望通过这篇实验报告,读
者们也能对图的遍历算法有更深入的理解和认识。

图的遍历实验报告.doc

图的遍历实验报告.doc

图的遍历实验报告实验4:图的遍历主题:图及其应用——图的遍历类;姓名:学生编号:完成日期:一、需求分析1。

问题描述:许多涉及图操作的算法都是基于图遍历操作的。

试着写一个程序来演示访问连通无向图上所有节点的操作。

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

从用户指定的节点开始,分别输出每次遍历下的节点访问顺序和相应生成树的边集。

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

暂时忽略里程,从北京开始。

4.实施提示: 假设一个图不超过30个节点,每个节点用一个数字表示(如果一个图有n个节点,它们的数字是1,2,分别为n)。

通过将一个图的所有边输入到一个图中,每个边是一对,边的输入顺序可以被限制。

请注意,生成树的边是有向边,端点的顺序不能颠倒。

5.选定内容:(1)。

借助堆栈类型(自行定义和实现),使用非递归算法实现深度优先遍历。

(2)以邻接表为存储结构,建立深度优先生成树和广度优先生成树,然后根据凹表或树打印生成树。

为了实现上述功能,需要图形的抽象数据类型。

抽象数据类型定义为:ADT图{数据对象v:v是一组具有相同特征的数据元素,称为顶点集。

数据关系r:R={VR} VR={ | v,wv和P(v,w),表示从v到w的弧,谓词P(v,w)定义弧的含义或信息}} ADT图2。

该抽象数据类型中的一些常量如下:#定义true1 #定义false 0 #定义ok 1 #定义max _ n 20//最大顶点数typedef char顶点类型[20];typedef枚举{DG,DN,AG,AN}图形种类;枚举BOOL {假,真};3.树的结构类型如下:Typedef结构{//圆弧节点和矩阵的int类型调整;//VRType是弧的类型。

图的遍历主题——图;图及其应用——图的遍历类;姓名:学生编号:完成日期:一、需求分析1。

问题描述:许多涉及图操作的算法都是基于图遍历操作的。

试着写一个程序来演示访问连通无向图上所有节点的操作。

实验五 图的遍历(深广度).doc

实验五 图的遍历(深广度).doc

实验五图的遍历(深/广度)实验内容图的深度优先搜索(DFS)和广度优先搜索(BFS)。

图的最小生成树和最短路径(选作)。

目的与要求掌握DFS和BFS原理,并用DFS和BFS打印图的顶点信息。

掌握图的最小生成树算法和最短路径算法。

程序中用户选择图的有向或无向,除对图作深,广度遍历之外,还对有向图作最短路径,对无向图作最小生成树。

#include <stdio.h>#include <stdlib.h>#define Infinity 1000#define MAX 20typedef struct{int vexnum; //顶点数目int arcnum; //弧数目char vexs[MAX]; //顶点向量int arcs[MAX][MAX]; //邻接矩阵char kind; //图的种类:有向图D,无向图U}MGraph;//图的建立MGraph Creat_MGraph(){MGraph G;int i,j,k,w;char v1,v2;printf("请输入图的种类(有向图(D),无向图(U)!\n");scanf("%c",&G.kind);printf("请输入顶点数目和弧数目!\n");scanf("%d%d",&G.vexnum,&G.arcnum);getchar();printf("请输入各个顶点(abc)!\n");for(i=0;i<G.vexnum;i++)scanf("%c",&G.vexs[i]);getchar();for(i=0;i<G.vexnum;i++){for(j=0;j<G.vexnum;j++)G.arcs[i][j]=Infinity;}for(i=0;i<G.arcnum;i++){printf("请输入第(%d) 条弧的起始点和它的权重(ccd)!\n",i+1);scanf("%c%c%d",&v1,&v2,&w);getchar();j=k=0;while(G.vexs[j]!=v1) j++; //起点while(G.vexs[k]!=v2) k++; //终点G.arcs[j][k]=w;if(G.kind=='U')G.arcs[k][j]=w;}return G;}int visited[MAX]; //标志数组,显示是否遍历//递归深度遍历调用函数void DFS(MGraph G,int i){int j;visited[i]=1;printf(" %c ",G.vexs[i]);for(j=0;j<G.vexnum;j++)if(!visited[j]&&G.arcs[i][j]<Infinity)DFS(G,j);}//深度遍历函数void M_DFSTraverse(MGraph G){int i;printf("深度遍历图结果如下:\n");for(i=0;i<G.vexnum;i++)visited[i]=0;for(i=0;i<G.vexnum;i++)if(!visited[i])DFS(G,i);printf("\n");}//广度遍历函数void M_BFSTraverse(MGraph G){int i,j,k,Q[MAX],w;j=k=0;printf("广度遍历图结果如下:\n");for(i=0;i<G.vexnum;i++)visited[i]=0;for(i=0;i<G.vexnum;i++)if(!visited[i]){visited[i]=1;printf(" %c ",G.vexs[i]);Q[k++]=i;while(j!=k){j++;for(w=0;w<G.vexnum;w++)if(!visited[w] && G.arcs[j][w]<Infinity){visited[w]=1;printf(" %c ",G.vexs[w]);Q[k++]=w;}}}printf("\n");}//最小生成树函数,对无向图适用void MiniSpanTree_PRIM(MGraph G,char u){char adjvex[MAX];int lowcost[MAX];int i,j,k=0,min;printf("图的最小生成树为:\n");while(G.vexs[k]!=u) k++;for(i=0;i<G.vexnum;i++)if(i!=k){adjvex[i]=u;lowcost[i]=G.arcs[k][i];}lowcost[k]=0;for(i=0;i<G.vexnum-1;i++){min=Infinity;for(j=0;j<G.arcnum;j++)if(lowcost[j] && lowcost[j]<min){min=lowcost[j];k=j;}printf("%c--(%d)--%c\n",adjvex[k],lowcost[k],G.vexs[k]);lowcost[k]=0;for(j=0;j<G.vexnum;j++)if(G.arcs[k][j]<lowcost[j]){adjvex[j]=G.vexs[k];lowcost[j]=G.arcs[k][j];}}}//求最短路径的函数,对有向图适用void ShortestPath_DIJ(MGraph G,char u){int P[MAX][MAX], //二维数组,标志最短路径上的点D[MAX], //记录最短路径的长度final[MAX], //标志是否求的它的最短路径i,j,v,w,v0,min;v0=0;while(G.vexs[v0]!=u) v0++;for(v=0;v<G.vexnum;++v){ //初始化D[v]=G.arcs[v0][v];final[v]=0;for(w=0;w<G.vexnum;w++)P[v][w]=0;if(D[v]<Infinity){P[v][v0]=1; P[v][v]=1;}}D[v0]=0;final[v0]=1;for(i=1;i<G.vexnum;i++){ //循环求出各个最短路径min=Infinity;for(w=0;w<G.vexnum;++w)if(!final[w])if(D[w]<min){v=w; min=D[w];}final[v]=1;for(w=0;w<G.vexnum;w++)if(!final[w] && (min+G.arcs[v][w]<D[w])){ //修改最短路径D[w]=min+G.arcs[v][w];for(j=0;j<G.vexnum;j++)P[w][j]=P[v][j];P[w][w]=1;}}printf("从已知点到其他各点的最短路径为:\n");for(v=0;v<G.vexnum;v++)if(final[v]){printf("%c--%c 的最短路径长度为%d ,路径为:",u,G.vexs[v],D[v]);for(w=0;w<G.vexnum;w++)if(P[v][w])printf(" %c ",G.vexs[w]);printf("\n");}}void main(){MGraph G;G=Creat_MGraph();M_DFSTraverse(G);M_BFSTraverse(G);if(G.kind=='U')MiniSpanTree_PRIM(G,'a'); //无向图就求它的最小生成树elseShortestPath_DIJ(G,'a'); //有向图就求它的最短路径}程序运行如下:(有向图)请输入图的种类(有向图(D),无向图(U)!D请输入顶点数目和弧数目!44请输入各个顶点(abc)!abcd请输入第(1) 条弧的起始点和它的权重(ccd)!ab4请输入第(2) 条弧的起始点和它的权重(ccd)!bc6请输入第(3) 条弧的起始点和它的权重(ccd)!cd5请输入第(4) 条弧的起始点和它的权重(ccd)!da8深度遍历图结果如下:a b c d广度遍历图结果如下:a c d b从已知点到其他各点的最短路径为:a--a 的最短路径长度为0 ,路径为:a--b 的最短路径长度为4 ,路径为: a ba--c 的最短路径长度为10 ,路径为: a b ca--d 的最短路径长度为15 ,路径为: a b c d Press any key to continue(无向图)请输入图的种类(有向图(D),无向图(U)!U请输入顶点数目和弧数目!44请输入各个顶点(abc)!abcd请输入第(1) 条弧的起始点和它的权重(ccd)!ab4请输入第(2) 条弧的起始点和它的权重(ccd)!bc6请输入第(3) 条弧的起始点和它的权重(ccd)!cd5请输入第(4) 条弧的起始点和它的权重(ccd)!da8深度遍历图结果如下:a b c d广度遍历图结果如下:a cb d图的最小生成树为:a--(4)--bb--(6)--cc--(5)--dPress any key to continue。

数据结构实验四图的深度优先与广度优先遍历

数据结构实验四图的深度优先与广度优先遍历

天津理工大学实验报告学院(系)名称:计算机与通信工程学院姓名学号专业计算机科学与技术班级2009级1班实验项目实验四图的深度优先与广度优先遍历课程名称数据结构与算法课程代码实验时间2011年5月12日第5-8节实验地点7号楼215 批改意见成绩教师签字:实验四图的深度优先与广度优先遍历实验时间:2011年5月12日,12:50 -15:50(地点:7-215)实验目的:理解图的逻辑特点;掌握理解图的两种主要存储结构(邻接矩阵和邻接表),掌握图的构造、深度优先遍历、广度优先遍历算法。

具体实验题目:(任课教师根据实验大纲自己指定)每位同学按下述要求实现相应算法:根据从键盘输入的数据创建图(图的存储结构可采用邻接矩阵或邻接表),并对图进行深度优先搜索和广度优先搜索1)问题描述:在主程序中提供下列菜单:1…图的建立2…深度优先遍历图3…广度优先遍历图0…结束2)实验要求:图的存储可采用邻接表或邻接矩阵;定义下列过程:CreateGraph(): 按从键盘的数据建立图DFSGrahp():深度优先遍历图BFSGrahp():广度优先遍历图实验报告格式及要求:按学校印刷的实验报告模版书写。

(具体要求见四)实验思路:首先,定义邻接矩阵和图的类型,定义循环队列来存储,本程序中只给出了有向图的两种遍历,定义深度优先搜索和广度优先搜索的函数,和一些必要的函数,下面的程序中会有说明,然后是函数及运行结果!#include<iostream>#include<cstdlib>using namespace std;#define MAX_VERTEX_NUM 20//最大顶点数#define MaxSize 100bool visited[MAX_VERTEX_NUM];enum GraphKind{AG,AN,DG,DN};//图的种类,无向图,无向网络,有向图,有向网络struct ArcNode{int adjvex;ArcNode * nextarc;};struct VNode{int data;ArcNode * firstarc;};struct Graph{VNode vertex[MAX_VERTEX_NUM];int vexnum,arcnum;//顶点数,弧数GraphKind kind;//图的类型};struct SeqQueue{int *base;int front,rear;SeqQueue InitQueue(){//循环队列初始化SeqQueue Q;Q.base = new int;Q.front=0;Q.rear=0;return Q;}void DeQueue(SeqQueue &Q,int &u){//出队操作u = *(Q.base+Q.front);Q.front = (Q.front+1)%MaxSize;}int QueueFull(SeqQueue Q){//判断循环队列是否满return (Q.front==(Q.rear+1)%MaxSize)?1:0;}void EnQueue(SeqQueue &Q,int x){//入队操作if(QueueFull(Q)){cout<<"队满,入队操作失败!"<<endl;exit(0);}*(Q.base+Q.rear) = x;Q.rear = (Q.rear+1)%MaxSize;void CreateDG(Graph & G,int n,int e){//初始化邻接表头结点int j;for(int i=0;i<n;++i){G.vertex[i].data=i;G.vertex[i].firstarc=NULL;}for(i=0;i<e;++i){cin>>i>>j;//输入边的信息ArcNode* s;s= new ArcNode;s->adjvex = j;s->nextarc = G.vertex[i].firstarc;G.vertex[i].firstarc = s;}}void Visit(Graph G,int u){cout<<G.vertex[u].data<<" ";}int FirstAdjVex(Graph G,int v){if(G.vertex[v].firstarc)return G.vertex[v].firstarc->adjvex;elsereturn -1;}int NextAdjVex(Graph G,int v,int w){ArcNode* p = G.vertex[v].firstarc;while(p->adjvex!=w)p = p->nextarc;if(p->nextarc)return p->nextarc->adjvex;elsereturn -1;}void DFSGrahp(Graph G,int v){visited[v]=true;Visit(G,v);//访问顶点V,对从未访问过的邻接点w递归调用DFS for(int w=FirstAdjVex(G,v);w!=0;w=NextAdjVex(G,v,w))if(!visited[w]) DFSGrahp(G,w);}void DFSTraverse(Graph G){//对图G做深度优先搜索for(int v=0;v<G.vexnum;++v)visited[v]=false;//初始化访问标志数组visitedfor(v=0;v<G.vexnum;++v)if(!visited[v]) DFSGrahp(G,v);//对尚未访问的顶点v调用DFS }void BFSGrahp(Graph G){//图的广度优先搜索SeqQueue Q;Q=InitQueue();int u;for(int v=0;v<G.vexnum;++v)if(!visited[G,v]){EnQueue(Q,v);//v入队列while(!((Q.front==Q.rear)?1:0)){DeQueue(Q,u);//对首元素出队,赋给uvisited[u]=true;Visit(G,u);for(int w=FirstAdjVex(G,u);w!=0;w=NextAdjVex(G,u,w)) //u的未访问过的邻接点w入队列if(!visited[w])EnQueue(Q,w);}}}int main(){Graph p;int n,e;cout<<"输入图的顶点及边数:"<<endl;cin>>n>>e;cout<<"创建图:"<<endl;CreateDG(p,n,e);cout<<"图的优先深度结果为:"<<endl;DFSTraverse(p);cout<<"图的广度优先结果为:"<<endl;BFSGrahp(p);printf("结果如上所示!\n");return 0;}。

图的遍历操作实验报告

图的遍历操作实验报告

图的遍历操作实验报告一、实验目的本次实验的主要目的是深入理解图的遍历操作的基本原理和方法,并通过实际编程实现,掌握图的深度优先遍历(DepthFirst Search,DFS)和广度优先遍历(BreadthFirst Search,BFS)算法,比较它们在不同类型图中的性能和应用场景。

二、实验环境本次实验使用的编程语言为 Python,开发环境为 PyCharm。

实验中使用的数据结构为邻接表来表示图。

三、实验原理(一)深度优先遍历深度优先遍历是一种递归的图遍历算法。

它从起始节点开始,沿着一条路径尽可能深地访问节点,直到无法继续,然后回溯到上一个未完全探索的节点,继续探索其他分支。

(二)广度优先遍历广度优先遍历则是一种逐层访问的算法。

它从起始节点开始,先访问起始节点的所有相邻节点,然后再依次访问这些相邻节点的相邻节点,以此类推,逐层展开。

四、实验步骤(一)数据准备首先,定义一个图的邻接表表示。

例如,对于一个简单的有向图,可以使用以下方式创建邻接表:```pythongraph ={'A':'B','C','B':'D','E','C':'F','D':,'E':,'F':}```(二)深度优先遍历算法实现```pythondef dfs(graph, start, visited=None):if visited is None:visited = set()visitedadd(start)print(start)for next_node in graphstart:if next_node not in visited:dfs(graph, next_node, visited)```(三)广度优先遍历算法实现```pythonfrom collections import deque def bfs(graph, start):visited ={start}queue = deque(start)while queue:node = queuepopleft()print(node)for next_node in graphnode:if next_node not in visited:visitedadd(next_node)queueappend(next_node)```(四)测试与分析分别使用深度优先遍历和广度优先遍历算法对上述示例图进行遍历,并记录遍历的顺序和时间开销。

图的遍历运算实验报告

图的遍历运算实验报告

软件技术基础实验六-----图的遍历运算班级:电信0901学号:**********姓名:***实验六图的遍历运算(1)实验题目:编写一个程序,实现图的遍历运算,在此基础上设计一个主程序完成如下功能(1)从指定顶点开始的深度优先遍历(递归实现)(2)从指定顶点开始的深度优先遍历(非递归实现)(3)从指定顶点开始的广度优先遍历(2)实验目的:1、掌握图的数据类型描述及特点。

2、掌握图的存储结构(邻接表和邻接矩阵)。

3、掌握图的遍历算法的实现。

(3)调试通过并正确执行给定功能要求的实验代码#include "stdafx.h"#include<stdio.h>#include<stdlib.h>#include <string.h>#define MAXVEX 100typedef char VertexType[3];typedef struct edgenode{ int adjvex;int value;struct edgenode *next;}ArcNode;typedef struct vexnode{ VertexType data;ArcNode *firstarc;}VHeadNode;typedef struct vertex{ int adjvex;VertexType data;}VType;typedef struct graph{ int n,e;VType vexs[MAXVEX];int edges [MAXVEX][MAXVEX];}AdjMatix;typedef struct{ int n,e;VHeadNode adjlist[MAXVEX];}AdjList;//将邻接矩阵g转化成邻接表G:void MatToList(AdjMatix g, AdjList *&G){ int i,j;ArcNode *p;G=(AdjList *)malloc(sizeof(AdjList));for (i=0;i<g.n;i++){ G->adjlist[i].firstarc=NULL;strcpy( G->adjlist[i].data,g.vexs[i].data);}for (i=0;i<g.n;i++)for(j=g.n-1;j>=0;j--)if (g.edges[i][j]!=0){ p=(ArcNode *)malloc(sizeof(ArcNode));p->value=g.edges[i][j];p->adjvex=j;p->next=G->adjlist[i].firstarc;G->adjlist[i].firstarc=p;}G->n=g.n;G->e=g.e;}//广度优先:void BFS(AdjList *G,int vi,FILE *fp3){int i,v,visited[MAXVEX];char s;int Qu[MAXVEX],front=0,rear=0;ArcNode *p;for (i=0;i<G->n;i++)visited[i]=0;s=vi+48;putc(s,fp3);visited[vi]=1;rear=(rear+1)%MAXVEX;Qu[rear]=vi;while(front!=rear){ front=(front+1)%MAXVEX;v=Qu[front];p=G->adjlist[v].firstarc;while(p!=NULL){ if(visited[p->adjvex]==0){ visited[p->adjvex]=1;s=p->adjvex+48;putc(s,fp3);rear=(rear+1)%MAXVEX;Qu[rear]=p->adjvex;}p=p->next;}}}//深度优先递归:int visited[MAXVEX];void DFS(AdjList *g,int vi,FILE *fp3) { ArcNode *p;char s;s=vi+48;putc(s,fp3);visited[vi]=1;p=g->adjlist[vi].firstarc;while(p!=NULL){ if (visited[p->adjvex]==0)DFS(g,p->adjvex,fp3);p=p->next;}}//深度优先非递归:void DFS1(AdjList *G,int vi,FILE *fp3) { ArcNode *p;ArcNode *St[MAXVEX];int top=-1,v;char s;s=vi+48;putc(s,fp3);visited[vi]=1;top++;St[top]=G->adjlist[vi].firstarc;while(top>-1){ p=St[top];top--;while(p!=NULL){ v=p->adjvex;if(visited[v]==0){ s=v+48;putc(s,fp3);visited[v]=1;top++;St[top]=G->adjlist[v].firstarc;break;}p=p->next;}}}void main(){ int i,j,h,x=2,y=0;FILE *fp,*fp1,*fp2,*fp3;fp=fopen("file1.txt","r");h=fgetc(fp)-48; //文件1为读入邻接矩阵的阶数给h fp1=fopen("file2.txt","r");int a[MAXVEX][MAXVEX];for(i=0;i<h;i++) //文件2为读入邻接矩阵a[i][j]for(j=0;j<h;j++){a[i][j]=fgetc(fp1)-48;if(a[i][j]==1) y++;}AdjMatix g;AdjList *G;char *vname[MAXVEX]={"a","b","c","d","e","f"};g.n=h;g.e=y;for(i=0;i<g.n;i++) strcpy(g.vexs[i].data,vname[i]);for(i=0;i<g.n;i++)for(j=0;j<g.n;j++)g.edges[i][j]=a[i][j];MatToList(g,G);fp2=fopen("file3.txt","r");x=fgetc(fp2)-48; //文件3为读入遍历的指定顶点xfp3=fopen("file4.txt","w"); //文件4为遍历结果fputs("从指定顶点x的广度优先遍历序列:\n",fp3);fputs("\t",fp3);BFS(G,x,fp3); fputs("\n",fp3);for(i=0;i<g.n;i++)visited[i]=0;fputs("从指定顶点x的深度优先遍历序列:\n",fp3);fputs("递归算法:",fp3);DFS(G,x,fp3);fputs("\n",fp3);for(i=0;i<g.n;i++) visited[i]=0;fputs("非递归算法:",fp3);DFS1(G,x,fp3);fputs("\n",fp3);fclose(fp);fclose(fp1);fclose(fp2);fclose(fp3);}(4)实验结果截图。

实验四__图的深度优先与广度优先遍历

实验四__图的深度优先与广度优先遍历

实验四图的深度优先与广度优先遍历实验题目:从键盘输入的数据创建图(图的存储结构可采用邻接矩阵或邻接表),并对图进行深度优先搜索和广度优先搜索(1)算法设计思路简介先定义邻接矩阵和邻接表类型,实现邻接表和邻接矩阵的相互转换,输出邻接表和邻接矩阵,再实现深度和广度优先遍历在主程序中提供下列菜单:1…图的建立2…深度优先遍历图3…广度优先遍历图0…结束(2)算法描述:可以用自然语言、伪代码或流程图等方式VertexType; //顶点类型MGraph; //图的邻接矩阵类型ArcNode; //定义邻接表类型void DispMat(MGraph g) //输出邻接矩阵void MatToList(MGraph g,ALGraph *&G) //将邻接矩阵g转换为邻接表Gvoid DispAdj(ALGraph *G) //输出邻接表void ListToMat(ALGraph *G,MGraph g) //将邻接表转换为邻接矩阵的形式void DFS(ALGraph *G,int v) //递归深度优先遍历void BFS(ALGraph *G,int v) //广度优先遍历(3)算法的实现和测试结果:包括算法运行时的输入、输出,实验中出现的问题及解决办法等#include<stdio.h>#include<malloc.h>#define max 100typedef struct //以下定义临接矩阵类型{int number;int info;}VertexType;typedef struct //图的定义{int edges[max][max];int n,e;VertexType vexs[max];}MGraph;//定义邻接表类型typedef struct ANode{int adjvex;struct ANode *nextarc; //指向下一条弧的指针int info; //存放弧的信息(权值)}ArcNode;typedef struct Vnode{int data;ArcNode *firstarc; //指向第一条弧}VNode;typedef VNode AdjList[max]; //AdjList是邻接表类型,把大表变成几个小的连接到一起typedef struct{AdjList adjlist;int n,e; //图中顶点数和和边数}ALGraph;int visited[max]; //全局数组用于判断后面节点是否被访问过void DispMat(MGraph g) //输出邻接矩阵{int i,j;for(i=0;i<g.n;i++){for(j=0;j<g.n;j++)if(g.edges[i][j]==0)printf("0 ");elseprintf("%d ",g.edges[i][j]);printf("\n");}}void MatToList(MGraph g,ALGraph *&G) //将邻接矩阵g转换为邻接表G{int i,j;int n=g.n;ArcNode *p;G=(ALGraph *)malloc(sizeof(ALGraph));for(i=0;i<n;i++) //给大的邻接表中所有头结点的指针域副初值G->adjlist[i].firstarc=NULL;for(i=0;i<n;i++) //检查邻接矩阵的每个元素for(j=0;j<n;j++)if(g.edges[i][j]!=0){p=(ArcNode *)malloc(sizeof(ArcNode));p->adjvex=j;p->info=g.edges[i][j];p->nextarc=G->adjlist[i].firstarc; //将*p连接到表后G->adjlist[i].firstarc=p;}G->e=g.e;G->n=g.n;}void DispAdj(ALGraph *G) //输出邻接表{int i;ArcNode *p;for(i=0;i<G->n;i++){p=G->adjlist[i].firstarc;if(p!=NULL)printf(" %d: ",i);while(p!=NULL){printf(" %d ",p->adjvex); //输出弧的终点p=p->nextarc;}printf("\n");}}void change(int visited[],ALGraph *G) //给全局变量visited赋初值{int i;for(i=0;i<G->n;i++)visited[i]=0;}void ListToMat(ALGraph *G,MGraph g) //将邻接表转换为邻接矩阵的形式{int i,j;int n=G->n;ArcNode *p;for(i=0;i<n;i++)for(j=0;j<n;j++)g.edges[i][j]=0;for(i=0;i<n;i++){p=G->adjlist[i].firstarc;while(p!=NULL){g.edges[i][p->adjvex]=p->info;p=p->nextarc;}}g.n=n;g.e=G->e;}void DFS(ALGraph *G,int v) //递归深度优先遍历{ArcNode *p;//change(visited,G);visited[v]=1; //第一个点设为已被访问并输出,接着以他为主进行遍历printf(" %d",v);p=G->adjlist[v].firstarc;while(p!=NULL){if(visited[p->adjvex]==0)DFS(G,p->adjvex);p=p->nextarc;}}void BFS(ALGraph *G,int v){ArcNode *p;int queue[max],front=0,rear=0; //定义循环队列并初始化int visited[max];int w,i;for(i=0;i<G->n;i++)visited[i]=0;printf(" %d ",v); //把输入的第v个作为第一个广度遍历的节点,一直这样进行下去visited[v]=1;rear=(rear+1)%max;queue[rear]=v; //把v入队while(front!=rear) //队列不为空的时候{front=(front+1)%max;w=queue[front];p=G->adjlist[w].firstarc;while(p!=NULL){if(visited[p->adjvex]==0) //当前节点未被访问{printf("%d ",p->adjvex);visited[p->adjvex]=1;rear=(rear+1)%max;queue[rear]=p->adjvex;}p=p->nextarc;}}printf("\n");}void main(){int i,j;MGraph g;ALGraph *G;int A[max][6];printf("请输入邻接矩阵:\n");for(i=0;i<6;i++)for(j=0;j<6;j++)scanf("%d",&A[i][j]);g.n=6;g.e=10;for(i=0;i<g.n;i++)for(j=0;j<g.n;j++)g.edges[i][j]=A[i][j]; //给邻接矩阵赋值printf("这是图的邻接矩阵的形式:");printf("\n");DispMat(g); //输出邻接矩阵的函数G=(ALGraph *)malloc(sizeof(ALGraph));MatToList(g,G);printf("这是图的邻接表的形式:");printf("\n");DispAdj(G);printf("从顶点0开始的深度优先遍历:\n");DFS(G,0);printf("\n");printf("从顶点0开始的广度优先遍历:\n");BFS(G,0);printf("\n");}。

图遍历的演示实习报告

图遍历的演示实习报告

图遍历的演示实习报告在计算机科学中,图遍历是一种重要的操作,用于访问图中的节点和边。

为了更深入地理解图遍历的原理和应用,我进行了一次关于图遍历的演示实习。

图是由节点(也称为顶点)和连接节点的边组成的数据结构。

图遍历的目的是按照特定的顺序访问图中的所有节点。

常见的图遍历算法有深度优先搜索(DepthFirst Search,简称 DFS)和广度优先搜索(BreadthFirst Search,简称 BFS)。

在实习中,我首先选择了深度优先搜索算法进行演示。

深度优先搜索就像是在一个迷宫中,选择一条路一直走到底,直到无法前进,然后回溯。

为了实现深度优先搜索,我使用了递归的方法。

以下是一个简单的深度优先搜索的 Python 代码示例:```pythondef dfs(graph, node, visited=):if node not in visited:print(node)visitedappend(node)for neighbor in graphnode:dfs(graph, neighbor, visited)graph ={'A':'B','C','B':'A','D','E','C':'A','F','D':'B','E':'B','F','F':'C','E'}dfs(graph, 'A')```在这个示例中,`dfs`函数接受一个图(以邻接表的形式表示)、当前节点和一个已访问节点的列表作为参数。

如果当前节点未被访问过,就将其打印出来并标记为已访问,然后对其邻居节点递归调用`dfs`函数。

接下来,我演示了广度优先搜索算法。

广度优先搜索则像是以层层扩散的方式访问节点。

它先访问起始节点的所有邻居,然后再依次访问邻居的邻居。

以下是广度优先搜索的 Python 代码示例:```pythonfrom collections import dequedef bfs(graph, start):visited =queue = deque(start)while queue:node = queuepopleft()if node not in visited:print(node)visitedappend(node) queueextend(graphnode) graph ={'A':'B','C','B':'A','D','E','C':'A','F','D':'B','E':'B','F','F':'C','E'}bfs(graph, 'A')```在这个示例中,使用了一个队列来实现广度优先搜索。

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

一.实验目的熟悉图的存储结构,掌握用单链表存储数据元素信息和数据元素之间的关系的信息的方法,并能运用图的深度优先搜索遍历一个图,对其输出。

二.实验原理深度优先搜索遍历是树的先根遍历的推广。

假设初始状态时图中所有顶点未曾访问,则深度优先搜索可从图中某个顶点 v 出发,访问此顶点,然后依次从 v 的未被访问的邻接点出发深度优先遍历图,直至图中所有与 v 有路径相通的顶点都被访问到;若此时图有顶点未被访问,则另选图中一个未曾访问的顶点作起始点,重复上述过程,直至图中所有顶点都被访问到为止。

图的邻接表的存储表示:#define MAX_VERTEX_NUM 20#define MAXNAME 10typedef char VertexType[MAXNAME];typedef struct ArcNode{int adjvex;struct ArcNode *nextarc;}ArcNode;typedef struct VNode{VertexType data;ArcNode *firstarc;}VNode,AdjList[MAX_VERTEX_NUM];typedef struct{AdjList vertices;int vexnum,arcnum;int kind;}ALGraph;三.实验容编写 LocateVex 函数, Create 函数, print 函数, main 函数,输入要构造的图的相关信息,得到其邻接表并输出显示。

四。

实验步骤1)结构体定义,预定义,全局变量定义。

#include"stdio.h"#include"stdlib.h"#include"string.h"#define FALSE 0#define TRUE 1#define MAX 20typedef int Boolean;#define MAX_VERTEX_NUM 20#define MAXNAME 10typedef char VertexType[MAXNAME];typedef struct ArcNode{int adjvex;struct ArcNode *nextarc;}ArcNode;typedef struct VNode{VertexType data;ArcNode *firstarc;}VNode,AdjList[MAX_VERTEX_NUM];typedef struct{AdjList vertices;int vexnum,arcnum;int kind;}ALGraph;ALGraph G;Boolean visited[MAX];int degree[MAX_VERTEX_NUM];// 定义一个数组求每一个顶点的总度数(无向图)或出度(有向图)。

2)编写LocateVex函数,确定所输入的边在G 中的位置,返回该边所在的行数或或列数。

int LocateVex(ALGraph G,VertexType v){int i,n;for(n=0;n<G.vexnum;n++){if(strcmp(v,G.vertices[n].data)==0)i=n;}return i;}3)编写 Create 函数,采用邻接表构造图G,返回结构体变量G的值,并统计每一个顶点的总度数或出度。

ALGraph Create(ALGraph G){int i,j,k;VertexType v1,v2;ArcNode *p;printf(" 请输入要构造的图的顶点数和弧数:\n");scanf("%d%d",&G.vexnum,&G.arcnum);printf(" 请输入每一个顶点的名字: \n");for(i=0;i<G.vexnum;i++){scanf("%s",&G.vertices[i].data);G.vertices[i].firstarc=NULL;}printf(" 各顶点的位置以及名称为:\n");for(i=0;i<G.vexnum;i++)printf("%6d%6s\n",i,G.vertices[i].data);printf(" 请输入要构造的是无向图还是有向图:无向用0 表示,有向用 1 表示: \n");scanf("%d",&G.kind);for(i=0;i<G.vexnum;i++)degree[i]=0;printf(" 请输入每条弧的始点和终点:\n");if(G.kind==1){for(k=0;k<G.arcnum;k++){scanf("%s%s",&v1,&v2);i=LocateVex(G,v1);j=LocateVex(G,v2);p=(ArcNode *)malloc(sizeof(ArcNode));p->adjvex=j;p->nextarc=G.vertices[i].firstarc;G.vertices[i].firstarc=p;degree[i]++;}}if(G.kind==0){for(k=0;k<G.arcnum;k++){scanf("%s%s",&v1,&v2);i=LocateVex(G,v1);j=LocateVex(G,v2);p=(ArcNode *)malloc(sizeof(ArcNode));p->adjvex=j;p->nextarc=G.vertices[i].firstarc;G.vertices[i].firstarc=p;degree[i]++;p=(ArcNode *)malloc(sizeof(ArcNode));p->adjvex=i;p->nextarc=G.vertices[j].firstarc;G.vertices[j].firstarc=p;degree[j]++;}}return G;}4)编写 print函数,实现对所构建的图的邻接表的输出。

void print(ALGraph G){int i;ArcNode *p;for(i=0;i<G.vexnum;i++){printf("%6d%6s",i,G.vertices[i].data);for(p=G.vertices[i].firstarc;p;p=p->nextarc)printf("%6d",p->adjvex);printf("\n");if(G.kind==1)printf(" 出度为: %6d\n",degree[i]);if(G.kind==0)printf(" 总度数为: %6d\n",degree[i]);}}5)编写 FirstAdjVex函数,返回v 的第一个邻接点的编号。

int FirstAdjVex(ALGraph G,int v){ArcNode *p;p=G.vertices[v].firstarc;if(p)return(p->adjvex);elsereturn -1;}6)编写 NextAdjVex 函数,返回 v 第一个之后未被访问过的下一个邻接点。

int NextAdjVex(ALGraph G,int v,int w){ArcNode *p;int i;for(p=G.vertices[v].firstarc;p;p=p->nextarc){if(w!=p->adjvex)i=0;else i=1;if(i&&p)return p->nextarc->adjvex;elsereturn -1;}}7)编写 DFS函数,从第i 个顶点出发递归地深度优先遍历图G。

void DFS(ALGraph G,int v){int w;visited[v]=TRUE;printf("%s\n",G.vertices[v].data);for(w=FirstAdjVex(G,v);w>=0;w=NextAdjVex(G,v,w))if(!visited[w])DFS(G,w);}8)编写 DFSTraverse 函数,对图G作深度优先遍历。

void DFSTraverse(ALGraph G){int v;for(v=0;v<G.vexnum;++v)visited[v]=FALSE;for(v=0;v<G.vexnum;++v)if(!visited[v])DFS(G,v);}9)编写 main 函数,把以上几个函数结合到一起,用邻接表实现对一个图的构造,输入要构造的边的相关信息(总弧数,顶点数,边的两个顶点的名称,有向图还是无向图),对其进行输出显示,并用深度优先搜索的方法遍历所构建的图。

main(){ALGraph G;G=Create(G);printf(" 邻接表为: \n");print(G);printf(" 深度遍历的结果为:\n");DFSTraverse(G);}五.实验结果源程序代码:#include"stdio.h"#include"stdlib.h"#include"string.h"#define FALSE 0#define TRUE 1#define MAX 20typedef int Boolean;#define MAX_VERTEX_NUM 20#define MAXNAME 10typedef char VertexType[MAXNAME]; typedef struct ArcNode{int adjvex;struct ArcNode *nextarc;}ArcNode;typedef struct VNode{VertexType data;ArcNode *firstarc;}VNode,AdjList[MAX_VERTEX_NUM]; typedef struct{AdjList vertices;int vexnum,arcnum;int kind;}ALGraph;ALGraph G;Boolean visited[MAX];int degree[MAX_VERTEX_NUM];int LocateVex(ALGraph G,VertexType v) {int i,n;for(n=0;n<G.vexnum;n++){if(strcmp(v,G.vertices[n].data)==0)i=n;}return i;}ALGraph Create(ALGraph G){int i,j,k;VertexType v1,v2;ArcNode *p;printf(" 请输入要构造的图的顶点数和弧数: \n");scanf("%d%d",&G.vexnum,&G.arcnum);printf(" 请输入每一个顶点的名字: \n");for(i=0;i<G.vexnum;i++){scanf("%s",&G.vertices[i].data);G.vertices[i].firstarc=NULL;}printf(" 各顶点的位置以及名称为: \n");for(i=0;i<G.vexnum;i++)printf("%6d%6s\n",i,G.vertices[i].data);printf(" 请输入要构造的是无向图还是有向图:无向用0 表示,有向用 1 表示: \n");scanf("%d",&G.kind);for(i=0;i<G.vexnum;i++)degree[i]=0;printf(" 请输入每条弧的始点和终点:\n"); if(G.kind==1){for(k=0;k<G.arcnum;k++){scanf("%s%s",&v1,&v2);i=LocateVex(G,v1);j=LocateVex(G,v2);p=(ArcNode *)malloc(sizeof(ArcNode));p->adjvex=j;p->nextarc=G.vertices[i].firstarc;G.vertices[i].firstarc=p;degree[i]++;}}if(G.kind==0){for(k=0;k<G.arcnum;k++){scanf("%s%s",&v1,&v2);i=LocateVex(G,v1);j=LocateVex(G,v2);p=(ArcNode *)malloc(sizeof(ArcNode));p->adjvex=j;p->nextarc=G.vertices[i].firstarc;G.vertices[i].firstarc=p;degree[i]++;p=(ArcNode *)malloc(sizeof(ArcNode));p->adjvex=i;p->nextarc=G.vertices[j].firstarc;G.vertices[j].firstarc=p;degree[j]++;}}return G;}void print(ALGraph G){int i;ArcNode *p;for(i=0;i<G.vexnum;i++){printf("%6d%6s",i,G.vertices[i].data);for(p=G.vertices[i].firstarc;p;p=p->nextarc)printf("%6d",p->adjvex);printf("\n");if(G.kind==1)printf(" 出度为: %6d\n",degree[i]);if(G.kind==0)printf(" 总度数为: %6d\n",degree[i]);}}int FirstAdjVex(ALGraph G,int v){ArcNode *p;p=G.vertices[v].firstarc;if(p)return(p->adjvex);elsereturn -1;}int NextAdjVex(ALGraph G,int v,int w){ArcNode *p;int i;for(p=G.vertices[v].firstarc;p;p=p->nextarc){if(w!=p->adjvex)i=0;else i=1;if(i&&p)return p->nextarc->adjvex;elsereturn -1;}}void DFS(ALGraph G,int v){int w;visited[v]=TRUE;printf("%s\n",G.vertices[v].data);for(w=FirstAdjVex(G,v);w>=0;w=NextAdjVex(G,v,w)) if(!visited[w])DFS(G,w);}void DFSTraverse(ALGraph G){int v;for(v=0;v<G.vexnum;++v)visited[v]=FALSE;for(v=0;v<G.vexnum;++v)if(!visited[v])DFS(G,v);}main(){ALGraph G;G=Create(G);printf(" 邻接表为: \n");print(G);printf(" 深度遍历的结果为:\n");DFSTraverse(G);}构造一个无向图G,如图所示。

相关文档
最新文档