图的遍历操作实验报告

实验三、图的遍历操作 一、 目的 掌握有向图和无向图的概念;掌握邻接矩阵和邻接链表建立图的存储结构;掌握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 MaxVertexNum 100 //定义最大顶点数 typedef struct{ char vexs[MaxVertexNum]; //顶点表 int edges[MaxVertexNum][MaxVertexNum]; //邻接矩阵,可看作边表 int n,e; //图中的顶点数n和边数e }MGraph; //用邻接矩阵表示的图的类型 //=========建立邻接矩阵======= void CreatMGraph(MGraph *G) { int i,j,k; char a; printf("Input VertexNum(n) and EdgesNum(e): "); scanf("%d,%d",&G->n,&G->e); //输入顶点数和边数 scanf("%c",&a); printf("Input Vertex string:"); for(i=0;in;i++) { scanf("%c",&a); G->vexs[i]=a; //读入顶点信息,建立顶点表 } for(i=0;in;i++) for(j=0;jn;j++) G->edges[i][j]=0; //初始化邻接矩阵 printf("Input edges,Creat Adjacency Matrix\n"); for(k=0;ke;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[MaxVertexNum]; //========DFS:深度优先遍历的递归算法====== void DFSM(MGraph *G,int i) { //以Vi为出发点对邻接矩阵表示的图G进行DFS搜索,邻接矩阵是0,1矩阵 int j; printf("%c",G->vexs[i]); //访问顶点Vi visited[i]=TRUE; //置已访问标志 for(j=0;jn;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;in;i++) visited[i]=FALSE; //标志向量初始化 for(i=0;in;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[MaxVertexNum]; //定义队列 for(i=0;in;i++) visited[i]=FALSE; //标志向量初始化 for(i=0;in;i++) cq[i]=-1; //队列初始化 printf("%c",G->vexs[k]); //访问源点Vk visited[k]=TRUE; cq[r]=k; //Vk已访问,将其入队。注意,实际上是将其序号入队 while(cq[f]!=-1) { //队非空则执行 i=cq[f]; f=f+1; //Vf出队 for(j=0;jn;j++) //依次Vi的邻接点Vj if(G->edges[i][j]==1 && !visited[j]) { //Vj未访问 printf("%c",G->vexs[j]); //访问Vj visited[j]=TRUE; r=r+1; cq[r]=j; //访问过Vj入队 } } } //==========main===== void main() { int i; MGraph *G; G=(MGraph *)malloc(sizeof(MGraph)); //为图G申请存空间 CreatMGraph(G); //建立邻接矩阵 printf("Print Graph DFS: "); DFS(G); //深度优先遍历 printf("\n"); printf("Print Graph BFS: "); BFS(G,3); //以序号为3的顶点开始广度优先遍历 printf("\n"); } 执行顺序: Input VertexNum(n) and EdgesNum(e): 8,9 Input Vertex string: 01234567 Input edges,Creat Adjacency Matrix 0 1 0 2 1 3 1 4 2 5 2 6 3 7 4 7 5 6

Print Graph DFS:01374256

Print Graph BFS:31704256

V6 V4 V5 V7

V2 V3 V1 V0

图G的示例 2. 邻接链表作为存储结构程序示例 #include"stdio.h" #include"stdlib.h" #define MaxVertexNum 50 //定义最大顶点数 typedef struct node{ //边表结点 int adjvex; //邻接点域 struct node *next; //链域 }EdgeNode; typedef struct vnode{ //顶点表结点 char vertex; //顶点域 EdgeNode *firstedge; //边表头指针 }VertexNode; typedef VertexNode AdjList[MaxVertexNum]; //AdjList是邻接表类型 typedef struct { AdjList adjlist; //邻接表 int n,e; //图中当前顶点数和边数 } ALGraph; //图类型 //=========建立图的邻接表======= void CreatALGraph(ALGraph *G) { int i,j,k; char a; EdgeNode *s; //定义边表结点 printf("Input VertexNum(n) and EdgesNum(e): "); scanf("%d,%d",&G->n,&G->e); //读入顶点数和边数 scanf("%c",&a); printf("Input Vertex string:"); for(i=0;in;i++) //建立边表 { scanf("%c",&a); G->adjlist[i].vertex=a; //读入顶点信息 G->adjlist[i].firstedge=NULL; //边表置为空表 } printf("Input edges,Creat Adjacency List\n"); for(k=0;ke;k++) { //建立边表 scanf("%d%d",&i,&j); //读入边(Vi,Vj)的顶点对序号 s=(EdgeNode *)malloc(sizeof(EdgeNode)); //生成边表结点 s->adjvex=j; //邻接点序号为j s->next=G->adjlist[i].firstedge; G->adjlist[i].firstedge=s; //将新结点*S插入顶点Vi的边表头部 s=(EdgeNode *)malloc(sizeof(EdgeNode)); s->adjvex=i; //邻接点序号为i s->next=G->adjlist[j].firstedge;

合集下载

实现图地遍历算法某实验报告材料

实现图地遍历算法某实验报告材料

实现图的遍历算法1.需求分析对于下图G,编写一个程序输出从顶点0开始的深度优先遍历序列(非递归算法)和广度优先遍历序列(非递归算法)。

2.系统设计1.用到的抽象数据类型的定义图的抽象数据类型定义:ADT Graph{数据对象V:V是具有相同特性的数据元素的集合,称为顶点集数据关系R:R={VR}VR={<v,w>|v,w∈V且P(v,w),<v,w>表示从v到w的弧,谓词P(v,w)定义了弧<v,w>的意义或信息}基本操作P:CreatGraph(&G,V,VR)初始条件:V是图的顶点集,VR是图中弧的集合操作结果:按V和VR的定义构造图GDestroyGraph(&G)初始条件:图G存在操作结果:销毁图GInsertVex(&G,v)初始条件:图G存在,v和图中顶点有相同特征操作结果:在图G中增添新顶点v……InsertArc(&G,v,w)初始条件:图G存在,v和w是G中两个顶点操作结果:在G中增添弧<v,w>,若G是无向的则还增添对称弧<w,v>……DFSTraverse(G,Visit())初始条件:图G存在,Visit是顶点的应用函数操作结果:对图进行深度优先遍历,在遍历过程中对每个顶点调用函数Visit一次且仅一次。

一旦Visit()失败,则操作失败BFSTraverse(G,Visit())初始条件:图G存在,Visit是顶点的应用函数操作结果:对图进行广度优先遍历,在遍历过程中对每个顶点调用函数Visit一次且仅一次。

一旦Visit()失败,则操作失败}ADT Graph栈的抽象数据类型定义:ADT Stack{数据对象:D={ai|ai∈ElemSet,i=1,2,…,n,n≥0}数据关系:R1={<ai-1,ai>|ai-1,ai∈D,i=2,…,n}约定an端为栈顶,ai端为栈底基本操作:InitStack(&S)操作结果:构造一个空栈SDestroyStack(&S)初始条件:栈S已存在操作结果:将S清为空栈StackEmpty(S)初始条件:栈S已存在操作结果:若栈S为空栈,则返回TRUE,否则FALSE……Push(&S,e)初始条件:栈S已存在操作结果:插入元素e为新的栈顶元素Pop(&S,&e)初始条件:栈S已存在且非空操作结果:删除S的栈顶元素,并用e返回其值StackTraverse(S,visit())初始条件:栈S已存在且非空操作结果:从栈底到栈顶依次对S的每个数据元素调用函数visit(),一旦visit()失败,则操作失效}ADT Stack队列的抽象数据类型定义:ADT Queue{数据对象:D={a i|a i∈ElemSet,i=1,2,…,n,n≥0}数据关系:Rl={<a i-1,a i>|a i-1,a i∈D,i=2,…,n}约定其中a i端为队列头,a n端为队列尾。

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

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

数据结构实验报告图的遍历讲解一、引言在数据结构实验中,图的遍历是一个重要的主题。

图是由顶点集合和边集合组成的一种数据结构,常用于描述网络、社交关系等复杂关系。

图的遍历是指按照一定的规则,挨次访问图中的所有顶点,以及与之相关联的边的过程。

本文将详细讲解图的遍历算法及其应用。

二、图的遍历算法1. 深度优先搜索(DFS)深度优先搜索是一种常用的图遍历算法,其基本思想是从一个顶点出发,沿着一条路径向来向下访问,直到无法继续为止,然后回溯到前一个顶点,再选择此外一条路径继续访问。

具体步骤如下:(1)选择一个起始顶点v,将其标记为已访问。

(2)从v出发,选择一个未被访问的邻接顶点w,将w标记为已访问,并将w入栈。

(3)如果不存在未被访问的邻接顶点,则出栈一个顶点,继续访问其它未被访问的邻接顶点。

(4)重复步骤(2)和(3),直到栈为空。

2. 广度优先搜索(BFS)广度优先搜索是另一种常用的图遍历算法,其基本思想是从一个顶点出发,挨次访问其所有邻接顶点,然后再挨次访问邻接顶点的邻接顶点,以此类推,直到访问完所有顶点。

具体步骤如下:(1)选择一个起始顶点v,将其标记为已访问,并将v入队。

(2)从队首取出一个顶点w,访问w的所有未被访问的邻接顶点,并将这些顶点标记为已访问,并将它们入队。

(3)重复步骤(2),直到队列为空。

三、图的遍历应用图的遍历算法在实际应用中有广泛的应用,下面介绍两个典型的应用场景。

1. 连通分量连通分量是指图中的一个子图,其中的任意两个顶点都是连通的,即存在一条路径可以从一个顶点到达另一个顶点。

图的遍历算法可以用来求解连通分量的个数及其具体的顶点集合。

具体步骤如下:(1)对图中的每一个顶点进行遍历,如果该顶点未被访问,则从该顶点开始进行深度优先搜索或者广度优先搜索,将访问到的顶点标记为已访问。

(2)重复步骤(1),直到所有顶点都被访问。

2. 最短路径最短路径是指图中两个顶点之间的最短路径,可以用图的遍历算法来求解。

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

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

问题描述:若用有向网表示网页的链接网络,其中顶点表示某个网页,有向弧表示网页之间的链接关系。

试设计一个网络蜘蛛系统,分别以广度优先和深度优先的策略抓取网页。

一、需求分析:1.本程序要求采用利用图实现广度优先搜索。

2.首先输入顶点的数量,然后是各顶点对应的字母,再输入各条弧(权值都置为1)。

3.在Dos界面输出从首个顶点开始的广度优先遍历序列。

4.测试数据输入输入顶点数和弧数:8 9输入8个顶点.输入顶点0:a输入顶点1:b输入顶点2:c输入顶点3:d输入顶点4:e输入顶点5:f输入顶点6:g输入顶点7:h输入9条弧.输入弧0:a b 1输入弧1:b d 1输入弧2:b e 1输入弧3:d h 1输入弧4:e h 1输入弧5:a c 1输入弧6:c f 1输入弧7:c g 1输入弧8:f g 1输出广度优先遍历: a b d h e c f g深度优先遍历: a b c d e f g h二、概要设计:抽象数据类型:图的定义:ADT Graph {数据对象V:V是具有相同特性的数据元素的集合,称为顶点集。

数据关系R:R={VR}VR={<v,w>|v,w∈v且P(v,w),<v,w>表示从v到w的弧,谓词P(v,w)定义了弧<v,w>的意义或信息}基本操作P:CreateGraph(&G,V,VR)初始条件:V是图的顶点集,VR是图中弧的集合操作结果:按V和VR的定义构造图GFirstAdjV ex(G,v)初始条件:图G存在,v是G中某个顶点操作结果:返回v的第一个邻接顶点,若顶点在G中没有邻接顶点,则返回“空”Next AdjV ex(G,v,w)初始条件:图G存在,v是G中某个顶点,w是v的邻接顶点操作结果:返回v的(相对于w的)下一个邻接顶点,若w是v的最后一个邻接点,则返回“空”visit(G, k)初始条件:图G存在操作结果:访问图G中的第K个节点Locate(G, c)初始条件:图G存在操作结果:访问图G中的c顶点DFS(G, v)初始条件:图G存在操作结果:以图G中的第v个节点为起点深度优先访问图GBFS(G)初始条件:图G存在操作结果:广度优先访问图G} ADT Graph算法的基本思想:(1)图的特点是没有首尾之分,所以算法的参数要指定访问的第一个顶点。

实验五 图的基本操作-遍历的实现

实验五    图的基本操作-遍历的实现

实验五图的遍历及其应用实现一、实验目的1.熟悉图常用的存储结构。

2.掌握在图的邻接矩阵和邻接表两种结构上实现图的两种遍历方法实现。

3.会用图的遍历解决简单的实际问题。

二、实验内容[题目一] :从键盘上输入图的顶点和边的信息,建立图的邻接表存储结构,然后以深度优先搜索和广度优先搜索遍历该图,并输出起对应的遍历序列. 试设计程序实现上述图的类型定义和基本操作,完成上述功能。

该程序包括图类型以及每一种操作的具体的函数定义和主函数。

提示:输入示例上图的顶点和边的信息输入数据为:5 7 DGA B C D EAB AE BC CD DA DB EC[题目二]:在图G中求一条从顶点 i 到顶点 s 的简单路径[题目三]:寻求最佳旅游线路(ACM训练题)在一个旅游交通网中,判断图中从某个城市A到B是否存在旅游费用在s1-s2元的旅游线路,为节省费用,不重游故地。

若存在这样的旅游线路则并指出该旅游线路及其费用。

输入:第一行:n //n-旅游城市个数第2行:A B s1 s2 //s1,s2-金额数第3行---第e+2行 ( 1≤e≤n(n-1)/2 ) 表示城市x,y之间的旅行费用,输入0 0 0 表示结束。

输出:第一行表示 A到B的旅游线路景点序列第二行表示沿此线路,从A到B的旅游费用设计要求:1、上机前,认真学习教材,熟练掌握图的构造和遍历算法,图的存储结构也可使用邻接矩阵等其他结构.2、上机前,认真独立地写出本次程序清单,流程图。

图的构造和遍历算法分别参阅讲义和参考教材事例图的存储结构定义参考教材相关函数声明:1、/* 输入图的顶点和边的信息,建立图*/void CreateGraph(MGraph &G)2、/* 深度优先搜索遍历图*/void DFSTraverse(Graph G, int v)3、/*广度优先搜索遍历图 */void BFSTraverse(Graph G, int v)4、4、/* 其他相关函数 */……三、实验步骤㈠、数据结构与核心算法的设计描述㈡、函数调用及主函数设计(可用函数的调用关系图说明)㈢程序调试及运行结果分析㈣实验总结四、主要算法流程图及程序清单1、主要算法流程图:2、程序清单(程序过长,可附主要部分)。

,图的遍历及最小生成树实验报告

,图的遍历及最小生成树实验报告

实验三最小生成树问题班级:计科1101班学号:0909101605姓名:杜茂鹏2013年5月23日一、实验目的掌握图的存储表示和以及图的最小生成树算法。

二、实验内容1.实现图的存储,并且读入图的内容。

2.利用普里姆算法求网络的最小生成树。

3.实现构造生成树过程中的连通分量抽象数据类型。

4.以文本形式输出对应图的最小生成树各条边及权值。

三、实验要求1.在上机前写出全部源程序;2.能在机器上正确运行程序;3.用户界面友好。

四、概要设计、首先采用图的邻接矩阵存储结构,然后从终端输入图的顶点名称、弧以及弧的权值建立邻接矩阵,并将图存储在文件Graph.txt中。

然后利用已经建好的图,分别对其进行深度、广度优先遍历,一次输出遍历的顶点最后建立此图的最小生成树,并将对应的边及权值写入文件graph_prim.txt 中。

六、详细设计实验内容(原理、操作步骤、程序代码)#include<stdio.h>#include<stdlib.h>#include<limits.h>#define INFINITY INT_MAX //最大值#define MAX_VERTEX_NUM 20 //最大顶点个数int visited[MAX_VERTEX_NUM];typedef struct ArcCell{int adj;int *info; //该弧相关信息的指针}ArcCell,AdjMatrix[MAX_VERTEX_NUM][MAX_VERTEX_NUM];typedef struct close{char adjvex;int lowcost;}closedge[MAX_VERTEX_NUM];typedef struct{char vexs[MAX_VERTEX_NUM]; //顶点向量AdjMatrix arcs; //邻接矩阵int vexnum,arcnum; //图的当前顶点数和弧数closedge cld;}MGraph;typedef struct QNode{char data;struct QNode *next;}QNode,*QueuePtr;typedef struct{QueuePtr front1;QueuePtr rear;}LinkQueue;void (*VisitFunc)(MGraph G,int v);void DFSTraverse(MGraph G,void (* Visit)(MGraph G,int v)); void DFS(MGraph G,int v);void InitQueue(LinkQueue &Q){Q.front1=Q.rear=(QueuePtr)malloc(sizeof(QNode));if(!Q.front1)exit(0);Q.front1->next=NULL;}void EnQueue(LinkQueue &Q,char e){QueuePtr p=(QueuePtr)malloc(sizeof(QNode));if(!p)exit(0);p->data=e;p->next=NULL;Q.rear->next=p;Q.rear=p;}char DeQueue(LinkQueue &Q){if(Q.front1==Q.rear)exit(0);QueuePtr p=Q.front1->next;char e=p->data;Q.front1->next=p->next;if(Q.rear==p)Q.rear=Q.front1;free(p);return e;}int QueueEmpty(LinkQueue Q){if(Q.front1==Q.rear)return 1;return 0;}int LocateVex(MGraph &G,char v1){int i=0;while(!(G.vexs[i]==v1))i++;return i;}char GetVex(MGraph G,int i){char u;u=G.vexs[i];return u;}int minimum(MGraph G,closedge cld){int mini=1000,s1;for(int i=0;i<G.vexnum;i++){if(cld[i].lowcost!=0&&mini>cld[i].lowcost){mini=cld[i].lowcost;s1=i;}}return s1;}void CreateUDN(MGraph &G){int IncInfo;printf("请分别输入顶点数/弧数/以及弧所含信息:");scanf("%d %d %d",&G.vexnum,&G.arcnum,&IncInfo);getchar();for(int i=0;i<G.vexnum;i++){ //构造顶点向量printf("请输入顶点:");scanf("%c",&G.vexs[i]);getchar();}for(int i=0;i<G.vexnum;i++) //初始化邻接矩阵for(int j=0;j<G.vexnum;j++){G.arcs[i][j].adj=INFINITY;G.arcs[i][j].info=NULL;}for(int k=0;k<G.arcnum;k++){char v1,v2;int w,i,j;printf("输入一条边依附的顶点及权值:"); //构造邻接矩阵scanf("%c %c %d",&v1,&v2,&w); //输入一条边依附的顶点及权值i=LocateVex(G,v1);j=LocateVex(G,v2);G.arcs[i][j].adj=w;if(IncInfo)*G.arcs[i][j].info=IncInfo;G.arcs[j][i]=G.arcs[i][j];getchar();}}//深度优先遍历void Visit(MGraph G,int v){printf("%c",G.vexs[v]);}void DFSTraverse(MGraph G,void (* Visit)(MGraph G,int v)){VisitFunc=Visit;for(int v=0;v<G.vexnum;v++)visited[v]=0;for(int v=0;v<G.vexnum;v++)if(!visited[v]){DFS(G,v);}}void DFS(MGraph G,int v){visited[v]=1;VisitFunc(G,v);for(int j=0;j<G.vexnum;j++)if(!visited[j]&&G.arcs[v][j].adj!=INFINITY)DFS(G,j);}void BFSTraverse(MGraph G,void(*Visit)(MGraph G,int v)) {LinkQueue Q;for(int v=0;v<G.vexnum;v++)visited[v]=0;InitQueue(Q);for(int v=0;v<G.vexnum;v++)if(!visited[v]){visited[v]=1;Visit(G,v);EnQueue(Q,G.vexs[v]);while(!QueueEmpty(Q)){DeQueue(Q);for(int j=0;j<G.vexnum;j++)if(!visited[j]&&G.arcs[v][j].adj!=INFINITY) {visited[j]=1;Visit(G,j);EnQueue(Q,G.vexs[j]);}}}}void MiniSpanTree_PRIM(MGraph G,char u){FILE *IN;if((IN=fopen("graph_prim.txt","w+"))==NULL){printf("file open error!");exit(1);}int k=LocateVex(G,u);for(int j=0;j<G.vexnum;j++)if(j!=k){G.cld[j].adjvex=u;G.cld[j].lowcost=G.arcs[k][j].adj;}G.cld[k].lowcost=0;for(int i=1;i<G.vexnum;i++){k=minimum(G,G.cld);printf("%c%c",G.cld[k].adjvex,G.vexs[k]);int m=LocateVex(G,G.cld[k].adjvex);printf("%d\n",G.arcs[m][k].adj);fprintf(IN,"%c,%c,%d",G.cld[k].adjvex,G.vexs[k],G.arcs[m][k].adj);fputs("\n",IN);G.cld[k].lowcost=0;for(int j=0;j<G.vexnum;j++)if(G.arcs[k][j].adj<G.cld[j].lowcost){G.cld[j].adjvex=G.vexs[k];G.cld[j].lowcost=G.arcs[k][j].adj;}}fclose(IN);}void menu(){printf("1.生成无向网G\n");printf("2.最小生成树\n");printf("3.深度遍历\n");printf("4.广度遍历\n");printf("0.退出\n");}int main(void){MGraph G;int m;do{menu();printf("输入你想要进行的操作的序号:");scanf("%d",&m);getchar();switch(m){case 1:CreateUDN(G);break;case 2:char u;u=GetVex(G,0);MiniSpanTree_PRIM(G,u);break;case 3:DFSTraverse(G,Visit);break;case 4:BFSTraverse(G,Visit);break;case 0:break;default:break;}}while(m);}七、测试结果(截图)主界面八、实验心得1拼写错误节应该避免2尽量用通俗易懂的标示符定义函数、变量3变量应该先定义再使用4应该从使用者的角度考虑,做出简洁的主界面5编好一个函数时应该加注释方便以后阅读时好理解。

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

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

【关键字】实验数据结构图的遍历实验报告篇一:【数据结构】图的保存和遍历实验报告《数据结构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");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 && visited[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);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图的保存与遍历");printf("\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) { case 1:CreateMGraph(G); printf("\n\t\t图的邻接矩阵保存建立完成\n");break; case 2:DFSTraverseM(G);break; case 3:BFSTraverseM(G);break; case 0:ch1='n';break; default:printf("\n\t\t输出错误!清重新输入!"); }3. 调试分析(1)调试过程中主要遇到哪些问题?是如何解决的?由于实习之初对邻接表的保存结构了解不是很清楚,所以在运行出了一个小错误,即在输出邻接表时,每个结点都少了一个邻接点。

图的遍历-实验报告

洛阳理工学院实验报告
visited[i]=0;
printf("该图不连通!");
printf("该图有%d个连通分量!\n");
return 0;
}
5.测试数据及结果
给出2组以上的测试数据并将运行结果截屏对应给出。

分别输入结点个数为4,5,弧数为4,3,具体运行结果如下图所示。

实验总结:
本次实验主要掌握了图的结构特征,以及邻接矩阵和邻接表存储结构的特点和实现。

掌握了在邻接矩阵或邻接表存储结构下图的深度优先和广度优先遍历算法思想及其程序实现。

实验初期遇到了一些问题,不过最后都在老师和同学的帮助下顺利的解决了。

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

实验报告一、实验目的和内容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 对带权图,则为权值类型。

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

{
EnQueue(&Q,p->ivex );
graph->adjlist [p->ivex ].markV =1;
printf("<%d,%d>\n",p->jvex ,p->ivex );
printf("%d ",p->ivex );
}
p=p->jlink ;
}
}
}
}
void main()
{
int u,v;
}EdgeNode;
typedef struct VexNode
{
int markV;
char info;
int num;
EdgeNode *firstedge;
}VexNode;
typedef struct
{
VexNode adjlist[MAX];
int vexnum,edgenum;
}Graph;
InsertVex(&G,v)
初始条件:图G存在,v和图中顶点有相同特征。
操作结果:在图G中增添新顶点v。
DeleteVex(&G,v)
初始条件:图G存在,v是G中某个顶点。
操作结果:删除G中顶点v及其相关的边。
InsertEdge(&G,v,w)
初始条件:图G存在,v和w是G中两个顶点。
操作结果:在G中增添边(v,w)。
int i;
printf("请输入连通无向图的顶点个数和边的条数:\n");
scanf("%d %d",&graph->vexnum,&graph->edgenum);

图遍历的演示实验报告书讲解

1.实验题目图遍历的演示2.需求分析本演示程序用VC++6.0编写,以邻接矩阵为存储结构,实现连通无向图的深度优先和广度优先遍历。

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

①输入形式:要先输入顶点个数和边的条数,然后依次输入顶点的值,再输入每条边两端的值;②输出形式:输出无向图的邻接矩阵,深度优先遍历序列及广度优先遍历序列。

③测试数据:测试结果:3.概要设计1)为了实现上述程序功能,需要定义无向图的抽象数据类型:class WXT {数据对象:tu={ddxl[maxsize],juzhen[maxsize][maxsize],n,bian }Bianwz(WXT tu,char v)操作结果:寻找V的位置GZWTU(WXT &tu)操作结果:数组邻接矩阵表示法构造无向图DYljdd(WXT tu,int i)初始条件:图已存在操作结果:顶点下标为i的顶点的第一个邻接顶点XYdd(WXT tu,int i,int k)初始条件:图已存在操作结果:顶点下标为i的顶点相对于k的下一个顶点,k为i的当前邻接顶点,二者都是顶点下标SDbl(WXT tu,int v)操作结果:无向图的深度优先遍历,从第v个顶点出发,v为顶点下标SDbl_V(WXT tu,int vex)操作结果:从vex开始深度遍历图GDbl(WXT tu,int a)操作结果:无向图的广度遍历,从第v个顶点出发,v为顶点下标2)本程序包含8个函数:①主函数main()②图的基本操作,寻找V的位置函数Bianwz(WXT tu,char v)③构造无向图函数GZWTU(WXT &tu)④邻接顶点操作函数DYljdd(WXT tu,int i)⑤邻接顶点操作函数XYdd(WXT tu,int i,int k)⑥深度优先遍历函数SDbl(WXT tu,int v)⑦从vex开始深度遍历图函数SDbl_V(WXT tu,int vex)⑧广度优先遍历函数GDbl(WXT tu,int a)各函数间关系如下:4.详细设计#include<iostream>#include<queue>using namespace std;const int maxsize=100;//最大顶点数queue<int>q;//----------------------------------------------------------------class WXT //无向图的邻接矩阵类型{public:int Bianwz(WXT tu,char v);//图的基本操作,寻找V的位置int GZWTU(WXT &tu);//数组邻接矩阵表示法构造无向图int DYljdd(WXT tu,int i);//顶点下标为i的顶点的第一个邻接顶点int XYdd(WXT tu,int i,int k);//顶点下标为i的顶点相对于k的下一个顶点,k为i的当前邻接顶点,二者都是顶点下标void SDbl(WXT tu,int v);//无向图的深度优先遍历,从第v个顶点出发,v为顶点下标void SDbl_V(WXT tu,int vex);// 从vex开始深度遍历图int GDbl(WXT tu,int a);//无向图的广度遍历,从第v个顶点出发,v为顶点下标char ddxl[maxsize];//顶点向量// AdjMatrixint juzhen[maxsize][maxsize];//邻接矩阵int n;//顶点数int bian; //边数};WXT tu; //申明一个无向图的邻接矩阵类型int biaozhi[maxsize];//设置标志数组int WXT::Bianwz(WXT tu,char v)//图的基本操作,寻找V的位置{int i=0;while(i<tu.n && v!=tu.ddxl[i])i++; if(i<tu.n)return i;//查找成功则返回顶点的下标elsereturn -1;}int WXT::GZWTU(WXT &tu) //数组邻接矩阵表示法构造无向图{char v1,v2;cout<<"请输入图的顶点数和边数:"<<endl;cin>>tu.n>>tu.bian;cout<<"请输入"<<tu.n<<"个顶点值:"<<endl;for(int i=0;i<tu.n;i++)//构造顶点向量cin>>tu.ddxl[i];for(int q=0;q<tu.n;q++)//初始化邻接矩阵for(int p=0;p<tu.n;p++)tu.juzhen[q][p]=0;for(int k=0;k<tu.bian;k++)//构造邻接矩阵{cout<<"输入第"<<k+1<<"条边两端的顶点值:"<<endl;cin>>v1>>v2;int a=Bianwz(tu,v1);int b=Bianwz(tu,v2);tu.juzhen[a][b]=1;tu.juzhen[b][a]=tu.juzhen[a][b];}cout<<endl;cout<<"该无向图的邻接矩阵表示为:\n";cout<<" ";for(int n=0;n<tu.n;n++)//输出顶点cout<<" "<<tu.ddxl[n];cout<<endl;for(int x=0;x<tu.n;x++)//输出邻接矩阵{ cout<<tu.ddxl[x]<<" ";for(int y=0;y<tu.n;y++)cout<<tu.juzhen[x][y]<<" ";cout<<endl;}return 1;}//GZWTUint WXT::DYljdd(WXT tu,int i)//顶点下标为i的顶点的第一个邻接顶点{int j=0;while(j < tu.n && tu.juzhen[i][j]!=1) j=j+1;if(j < tu.n)return j;elsereturn -1;}int WXT::XYdd(WXT tu,int i,int k)//顶点下标为i的顶点相对于k的下一个顶点, { //k为i的当前邻接顶点,二者都是顶点下标int j=k+1;while(j < tu.n && tu.juzhen[i][j]!=1) j=j+1;if(j < tu.n)return j;elsereturn -1;}void WXT::SDbl(WXT tu,int v)//无向图的深度优先遍历,从第v个顶点出发,v为顶点下标{biaozhi[v]=1;cout<<tu.ddxl[v]<<" ";int w;for(w=DYljdd(tu,v);w>=0;w=XYdd(tu,v,w)){if(!biaozhi[w])SDbl(tu,w); //递归遍历}}void WXT::SDbl_V(WXT tu,int vex)// 从vex开始深度遍历图//{for(int i = 0;i < tu.n;i++) //访问数组初始化biaozhi[i]=0;SDbl(tu,vex); //先对图从指定定点访问for(int v = 0;v < tu.n;v ++)//对可能出现的子图遍历if(!biaozhi[v])SDbl(tu,v);}int WXT::GDbl(WXT tu,int a)//无向图的广度遍历,从第v个顶点出发,v为顶点下标{q.empty();int v,u,w;v=a;for(v=a-1;v<tu.n;v++)if(!biaozhi[v]){biaozhi[v]=1;cout<<tu.ddxl[v]<<" ";q.push(v);while(!q.empty()){u=q.front();q.pop();for(w=DYljdd(tu,u);w>=0;w=XYdd(tu,u,w))if(!biaozhi[w]){biaozhi[w]=1;cout<<tu.ddxl[w]<<" ";q.push(w);}}}return 1;}//----------------------------------------------------------------void main(){int a;WXT t;cout<<"*********************************"<<endl;cout<<" 无向图遍历的演示程序"<<endl;cout<<"*********************************"<<endl;t.GZWTU(tu);cout<<"请输入您要深度遍历图的起点(顶点的坐标1~"<<tu.n<<"):"<<endl;cin>>a;cout<<"深度优先遍历为:"<<endl;t.SDbl_V(tu,a-1);//因为下标从0开始cout<<endl;cout<<"广度优先遍历为:"<<endl;for(int v=0;v<tu.n;v++)biaozhi[v]=0;t.GDbl(tu,a);cout<<endl;cout<<"感谢您的使用!!!"<<endl;}5.调试分析遇到问题:①如何储存数据;②如何实现深度优先遍历;③如何实现广度优先遍历;④输出了顶点再次输出;解决方法:①用邻接矩阵储存,相通的两个点为“1”;不通的为“0”;②确定起点后,输出起点,然后输出起点矩阵中第一个为“1”对应的顶点值;然后再输出此顶点值矩阵中第一个为“1”且没有输出过的顶点值,以此类推,直至输出完所有顶点值;③确定起点后,输出起点,然后输出起点矩阵中所有为“1”的顶点值,然后输出起点第一个为“1”的顶点值的所有为“1”的顶点值,然后输出起点第二个为“1”的顶点值的所有为“1”的顶点值,以此类推,直至输出完所有顶点值;④设置一个标志baozhi[maxsize],初始化为“0”,没输出一个值就赋值为“1”;遍历时,biaozhi[N]为“1”的不输出,接着遍历;6.使用说明程序名为图遍历的演示.exe,运行环境为VC++6.0。

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