数据结构实验-图的储存与遍历
数据结构实验五---图的遍历及其应用实现
数据结构实验五---图的遍历及其应用实现实验五图的遍历及其应用实现一、实验目的1.熟悉图常用的存储结构。
2.掌握在图的邻接矩阵和邻接表两种结构上实现图的两种遍历方法实现。
3.会用图的遍历解决简单的实际问题。
二、实验内容[题目] :从键盘上输入图的顶点和边的信息,建立图的邻接表存储结构,然后以深度优先搜索和广度优先搜索遍历该图,并输出起对应的遍历序列. 试设计程序实现上述图的类型定义和基本操作,完成上述功能。
该程序包括图类型以及每一种操作的具体的函数定义和主函数。
三、实验步骤(一)、数据结构与核心算法的设计描述:本实验主要在于图的基本操作,关键是图的两种遍历,仔细分析图的遍历的特点,不难发现,其符合递归的特点,因此可以采用递归的方法遍历。
本实验图的存储结构主要采用邻接表,总共分为四个模块:图的创建、位置的查找、深度优先遍历、广度优先遍历。
以下是头文件中数据结构的设计和相关函数的声明:#include#include#include#nclude#define OVERFLOW -2#define MAX_VERTEX_NUM 50 //最大顶点数#define MAXQSIZE 100# define OK 1typedef int VRType;typedef int InfoType;typedef int QElemType;typedef enum{DG,DN,UDG,UDN}GraphKind;typedef struct ArcNode // 弧结点{int adjvex; //邻接点域,存放与Vi邻接的点在表头数组中的位置struct ArcNode *nextarc; //链域指向vi的下一条边或弧的结点,InfoType *info; //定义与弧相关的权值,无权则为0 }ArcNode;typedef struct VNode //表头结点{char vexdata; //存放顶点信息struct ArcNode *firstarc; //指示第一个邻接点}VNode,AdjList[MAX_VERTEX_NUM];typedef struct{ //图的结构定义AdjList vertices; //顶点向量int vexnum, arcnum; //vexnum为顶点数arcnum为弧或边的个数GraphKind kind; // 图的种类标志}MGraph;typedef struct Queue //构建循环队列{QElemType *base;int front;int rear;}Queue;void CreateGraph(MGraph &G); //图的创建void DFSTraverse(MGraph &G) ; //深度优先遍历void BFSTraverse(MGraph &G); //广度优先遍历int LocateVex(MGraph &G, char &v);//查找顶点v的位置(二)、函数调用及主函数设计void main(){int x;MGraph G;CreateGraph(G);cout<<"创建图成功!"<<endl;< p="">cout<<"1 深度优先搜索"<<endl<<"2 p="" 广度优先搜索"<<endl;<="">cin>>x;if(x==1){DFSTraverse(G);cout<<"深度优先搜索结束!"<<endl;< p="">}else if(x==2){BFSTraverse(G);cout<<"广度优先搜索结束!"<<endl;< p="">}elsecout<<"输入有误!"<<endl<<"再见!"<<endl;< p="">}(三)、实验总结由于图的基本操作在图这一章节中起着很主要的作用,所以在实验前就对实验做了充分的准备,实验的成功核心在于两种遍历的实现,因此只有充分理解遍历算法的精髓,才能更好的做好实验。
数据结构实验报告图的遍历
数据结构实验报告图的遍历一、实验目的本实验旨在通过实践的方式学习图的遍历算法,掌握图的深度优先搜索(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同样是一种遍历图的算法,其基本思想是从图的某一顶点开始,首先访问其所有邻接点,然后再依次访问邻接点的邻接点,直到所有顶点都被访问过为止。
【数据结构】图的存储和遍历实验报告
(2) 经验和体会:
必须培养严谨的科学态度。自己在编程时经常因为一些类似于“少了 分号”的小错误而导致错误,不够认真细致,这给自己带来了许多麻 烦。编程是一件十分严谨的事情,容不得马虎。所以在今后自己一定 要培养严谨的科学态度。我想这不仅是对于程序设计,做任何事都应 如此。
4. 测试结果
采用测试数据,列出实际的输入、输出结果。
case 0:ch1='n';break; default:printf("\n\t\t输出错误!清重新输入!"); } } }
3. 调试分析
(1) 调试过程中主要遇到哪些问题?是如何解决 的?
由于实习之初对邻接表的存储结构了解不是很清楚,所以在运行出了 一个小错误,即在输出邻接表时,每个结点都少了一个邻接点。通过 仔细分析,发现是输出邻接表的语句不对,其中的for()循环语句 中的控制条件:p->next!=NULL出了问题。将其改成p!=NULL后,邻 接表便可顺利输出。下面就是经修改后以有向图G1和无向图G2为例业 级 01 __班 姓名学号2010年1 0月 9日
1.
上机题目: 图的存储和遍历
2. 详细设计
#include<stdio.h> #define GRAPHMAX 10 #define FALSE 0 #define TRUE 1 #define error printf #define QueueSize 30 typedef 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;
数据结构课程设计图的存储与遍历报告
数据结构课程设计图的存储与遍历报告《数据结构》课程设计题目图的存储与遍历学生姓名指导教师学院专业班级完成时间目录第一章课程设计目的 (2)第二章课程设计内容和要求 (2)第三章课程设计分析 (3)第四章算法描述 (4)第五章源代码 (8)第六章运行结果分析 (13)第七章结束语 (15)第八章参考文献 (15)第一章课程设计目的本学期我们对《数据结构》这门课程进行了学习。
这门课程是一门实践性非常强的课程,为了让大家更好地理解与运用所学知识,提高动手能力,我们进行了此次课程设计实习。
这次课程设计不但要求实习者掌握《数据结构》中的各方面知识,还要求实习者具备一定的C语言基础和编程能力。
具体说来,这次课程设计主要有两大方面目的。
一是让实习者通过实习掌握《数据结构》中的知识。
对于《图的存储与遍历》这一课题来说,所要求掌握的数据结构知识主要有:图的邻接表存贮结构、队列的基本运算实现、邻接表的算法实现、图的广度优先搜索周游算法实现、图的深度优先搜索周游算法实现。
二是通过实习巩固并提高实习者的C语言知识,并初步了解Visual C++的知识,提高其编程能力与专业水平。
第二章课程设计内容和要求2.1课程设计内容该课题要求以邻接表的方式存储图,输出邻接表,并要求实现图的深度、广度两种遍历。
2.1.1图的邻接表的建立与输出对任意给定的图(顶点数和边数自定),并且对有向图与无向图都应进行讨论,根据邻接表的存储结构建立图的邻接表并输出之。
尽量用图形化的方式输出邻接表。
2.1.2 图的遍历的实现图的遍历包括图的广度优先遍历与深度优先遍历。
对于广度优先遍历应利用队列的五种基本运算(置空队列、进队、出队、取队头元素、判队空)来实现。
首先建立一空队列,从初始点出发进行访问,当被访问时入队,访问完出队。
并以队列是否为空作为循环控制条件。
对于深度优先遍历则采用递归或非递归算法来实现。
2.2 运行环境该程序的运行环境为Windows xp系统,Microsoft Visual C++6.0版本。
数据结构实验---图的储存与遍历
数据结构课程实验报告一、实验目的掌握图这种复杂的非线性结构的邻接矩阵和邻接表的存储表示, 以及在此两种常用存储方式下深度优先遍历(DFS)和广度优先遍历(BFS)操作的实现。
二、实验内容与实验步骤题目1: 对以邻接矩阵为存储结构的图进行DFS和BFS遍历问题描述: 以邻接矩阵为图的存储结构, 实现图的DFS和BFS遍历。
基本要求:建立一个图的邻接矩阵表示, 输出顶点的一种DFS和BFS序列。
测试数据: 如图所示题目2: 对以邻接表为存储结构的图进行DFS和BFS遍历问题描述: 以邻接表为图的存储结构, 实现图的DFS和BFS遍历。
基本要求:建立一个图的邻接表存贮, 输出顶点的一种DFS和BFS序列。
测试数据: 如图所示三、附录:在此贴上调试好的程序。
#include<stdio.h>#include<malloc.h>#include<string.h>#define M 100typedef struct node{char vex[M][2];int edge[M ][ M ];int n,e;}Graph;int visited[M];Graph *Create_Graph(){ Graph *GA;int i,j,k,w;GA=(Graph*)malloc(sizeof(Graph));printf ("请输入矩阵的顶点数和边数(用逗号隔开): \n");scanf("%d,%d",&GA->n,&GA->e);printf ("请输入矩阵顶点信息: \n");for(i = 0;i<GA->n;i++)scanf("%s",&(GA->vex[i][0]),&(GA->vex[i][1]));for (i = 0;i<GA->n;i++)for (j = 0;j<GA->n;j++)GA->edge[i][j] = 0;for (k = 0;k<GA->e;k++){ printf ("请输入第%d条边的顶点位置(i,j)和权值(用逗号隔开): ",k+1);scanf ("%d,%d,%d",&i,&j,&w);GA->edge[i][j] = w;}return(GA);}void dfs(Graph *GA, int v){ int i;printf("%c%c\n",GA->vex[v][0],GA->vex[v][1]);visited[v]=1;for(i=0; i<GA->n; i++)if (GA->edge[v][i]==1 && visited[i]==0) dfs(GA, i);}void traver(Graph *GA){ int i;for(i=0; i<GA->n; i++)visited[i]=0;for(i=0; i<GA->n;i++)if(visited[i]==0)dfs(GA, i);}void bfs( Graph *GA, int v){ int j,k,front=-1,rear=-1;int Q[M];printf("%c%c\n",GA->vex[v][0],GA->vex[v][1]); visited[v]=1;rear=rear+1;Q[rear]=v;while (front!=rear){ front=front+1;k=Q[front];for (j=0; j<GA->n; j++)if (GA->edge[k][j]==1 && visited[j]==0){ printf("%c%c\n",GA->vex[j][0],GA->vex[j][1]);visited[j]=1;rear=rear+1;Q[rear]=j;}}}void traver1(Graph *GA){ int i;for (i=0; i<GA->n;i++)visited[i]=0;for (i=0; i<GA->n; i++)if (visited[i]==0)bfs(GA, i);}typedef struct NODE{ int adjvex;struct NODE *next;}ENode;typedef struct NODE1{ char vex[2];ENode *first;} VexNode;typedef struct FS1{VexNode GL[M];int bian,top;}FS;FS *CreateGL( ){ FS *kk=(FS *)malloc(sizeof(FS));int i,j,k;ENode *s;printf("请输入顶点数和边数(用逗号隔开): \n");scanf("%d,%d",&kk->top, &kk->bian);printf("请输入顶点信息: \n");for (i=0; i<kk->top; i++){ scanf("%s",kk->GL[i].vex);kk->GL[i].first=NULL; }printf("请输入边的信息(i,j): \n");for (k=0;k<kk->bian;k++){ scanf("\n%d,%d",&i,&j);s =(ENode*)malloc(sizeof(ENode));s->adjvex=j;s->next=kk->GL[i].first;kk->GL[i].first =s;}return kk;}void DFS(FS *kk, int v){ ENode *w; int i;printf("%s\n",kk->GL[v].vex); visited[v]=1;w=kk->GL[v].first ;while (w!=NULL){ i=w->adjvex;if (visited[i]==0)DFS(kk,i);w=w->next;}}void TRAVER(FS *kk){ int i;for(i=0; i<kk->top;i++)visited[i]=0;for(i=0; i<kk->top; i++)if(visited[i]==0)DFS(kk, i);}void BFS(FS *kk, int v){ int Q[M], front=-1,rear=-1;ENode *w;int i, k;printf("%s\n",kk->GL[v].vex);visited[v]=1;rear=rear+1; Q[rear]=v;while (front!=rear){ front=front+1;k=Q[front];w=kk->GL[k].first;while(w!=NULL){ i=w->adjvex;if( visited[i]==0){ visited[i]=1; printf("%s",kk->GL[i].vex);rear=rear+1; Q[rear]=i;}w=w->next;}}}void TRAVER1(FS *kk){ int i;for(i=0; i<kk->top;i++) visited[i]=0;for(i=0; i <kk->top;i++)if(visited[i]==0)BFS(kk,i);}int main(){int i=0;Graph *p;FS *q;while(i=1){/*建立菜单*/char jz[30]={"1.创建邻接矩阵"};char jd[30]={"2.邻接矩阵DFS遍历"};char jb[30]={"3.邻接矩阵BFS遍历"};char bg[30]={"4.创建邻接表"};char bd[30]={"5.邻接表DFS遍历"};char bb[30]={"6.邻接表BFS遍历"};char tc[30]={"7.退出"};char mn[30]={"菜单"};int l=strlen(jd);int o=strlen(mn);int m,n;printf("\n");for(m=0;m<=(2*l-o)/2;m++)printf(" ");printf("%s",mn);for(m=0;m<=(2*l-o)/2;m++)printf(" ");printf("\n");for(m=0;m<=2*l;m++)printf("*");printf("\n");printf("* %s *\n* %s*\n* %s *\n* %s *\n* %s *\n* %s *\n* %s*\n",jz,jd,jb,bg,bd,bb,tc);for(m=0;m<=2*l;m++)printf("*");printf("\n");/*选择功能*/printf("请输入所需功能序号: ");scanf("%d",&n);switch(n){case 1: p=Create_Graph();break;case 2: traver(p);break;case 3: traver1(p);break;case 4: q=CreateGL();break;case 5: TRAVER(q);break;case 6: TRAVER1(q);break;case 7: return 0;default:printf("输入功能序号有误!\n");}}return 0;}四、运行结果:在此把运行结果从屏幕上拷下来贴在此五、心得体会:测试数据要注意现实中矩阵是从1开始, 而数组里是从0开始。
图的两种存储和遍历.doc
图的两种存储和遍历实验7图的两种存储和遍历一、实验内容:(1)键盘输入数据,分别建立有向图和无向图邻接表。
(2)输出邻接表。
(3)基于有向图的邻接表计算每个顶点的度,并输出。
(4)利用邻接表存储实现无向图的深度优先遍历。
(5)利用邻接表存储实现无向图的广度优先遍历。
(6)在主功能中设计一个简单的菜单,分别调试上述算法。
第二,源代码:#包含#包含#定义最大顶点数20 #定义确定1 #定义错误0 #定义溢出0 int访问[最大顶点数];//表节点typedef结构ArcNode { int adjvex构造ArcNode * nextarcchar * info} ArcNode//头节点typedef结构VNode {char数据;弧节点*首弧;}虚拟节点,列出[最大顶点数];//图结构typedef结构{AdjList顶点;int vexnum,arcnum} ALGraph//用于BFS遍历的附加链队列节点结构typedefstructqcode {intdata};结构QNode *下一步;}QNode,* QueuePtr//链队列typedef结构{QueuePtr前端;队列后部;}链接队列;//初始化链组intinitqueue(link queue q){ q . front=q . reason=(queue ptr)malloc(sizeof(qcode));如果(!Q.front)出口(OVERFLOW);问:前线-一、实验内容:(1)键盘输入数据,分别建立有向图和无向图邻接表。
(2)输出邻接表。
(3)基于有向图的邻接表计算每个顶点的度,并输出。
(4)利用邻接表存储实现无向图的深度优先遍历。
(5)利用邻接表存储实现无向图的广度优先遍历。
(6)在主功能中设计一个简单的菜单,分别调试上述算法。
第二,源代码:#包含#包含#定义最大顶点数20 #定义确定1 #定义错误0 #定义溢出0 int访问[最大顶点数];//表节点typedef结构ArcNode { int adjvex构造ArcNode * nextarcchar * info} ArcNode//头节点typedef结构VNode {char数据;弧节点*首弧;}虚拟节点,列出[最大顶点数];//图结构typedef结构{AdjList顶点;int vexnum,arcnum} ALGraph//用于BFS遍历的附加链队列节点结构typedefstructqcode {intdata};结构QNode *下一步;}QNode,* QueuePtr//链队列typedef结构{QueuePtr前端;队列后部;}链接队列;//初始化链组intinitqueue(link queue q){ q . front=q . reason=(queue ptr)malloc(sizeof(qcode));如果(!Q.front)出口(OVERFLOW);q . front:wordfan div;I)。
数据结构实验报告九—图的遍历
问题描述:若用有向网表示网页的链接网络,其中顶点表示某个网页,有向弧表示网页之间的链接关系。
试设计一个网络蜘蛛系统,分别以广度优先和深度优先的策略抓取网页。
一、需求分析: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、实验目的掌握图这种复杂的非线性结构的邻接矩阵和邻接表的存储表示,以及在此两种常用存储方式下深度优先遍历(dfs)和广度优先遍历(BFS)操作的实现。
2、实验预备知识(1)图的存储结构:邻接矩阵表示法和邻接表表示法。
邻接矩阵表示法除了要用一个二维数组存储用于表示顶点间相邻关系的邻接矩阵外,还需用一个一维数组来存储顶点信息,另外还有图的顶点数和边数。
邻接表表示法类似于树的孩子链表表示法。
(2)图的遍历方法有深度优先遍历(Depth-First Traersal)和广度优先遍历(Breadth-First Traversal),简称 DFS和BFS。
DFS对图遍历时尽可能先对纵深方向进行搜索;BFS是类似于树的按层次遍历。
3、实验内容题目1对以邻接矩阵为存储结构的图进行 DFS和 BFS遍历(1) 问题描述:以邻接矩阵为图的存储结构,实现图的DFS和BFS遍历。
(2) 基本要求:建立一个图的邻接矩阵表示,输出顶点的一种DFS和BFS序列。
(3) 测试数据:如图4.18所示。
(4) 实现提示:图的DFS遍历可通过递归调用或用栈来实现。
其思想是:只要当前结点未访问过,就访问该结点,沿着其一条分支深入下去,每深入一个未访问过的结点,就访问这个结点,然后从这个结点继续进行DFS遍历。
在这一过程中,若深入时遇到一个已访问过的结点,则查找是否有与这个结点相邻的下一个未访问过的结点。
若有则继续深人,否则将退回到这个结点的前一个结点,再找下一个相邻的本访问过的结点,……如此进行下去,直到所有的结点都被访问过。
BFS遍历可利用队列来帮助实现,也可以用栈。
实现方法与二叉树的层次遍历类似。
题目2对以邻接表为存储结构的图进行DFS和BFS遍历(1) 问题描述:以邻接表为存储结构,实现图的DFS和BFS遍历。
(2) 基本要求:建立一个图的邻接表存储,输出顶点的一种DFS和BFS序列。
(3) 测试数据:如图4.19所示:(4) 实现提示:以邻接表为存储结构的图的DFS和BFS算法的实现思想与以邻接矩阵为存储结构的实现是一样的。
图的存储与遍历
void BFSTraverse(Graph G)
{ //按广度优先非递归遍历图G。类似于树的层次遍历。 for (v=0; v<G.vexnum; ++v) visited[v]=0; //访问标志初始化 InitQueue(Q); //辅助队列Q for(v=0; v<G.vexnum; ++v)
}//while
例:下图采用邻接矩阵存储结构,给出从顶点A出发的 深度优先和广度优先遍历图的序列。
A B C E
深度优先遍历序列:A B E C D
D
if( !visited[v] ) //v尚未访问,从v出发广度优先遍历
{
}//BFSTraverse 下页显示
}//if
//从v出发广度优先遍历
visited[v]=1; Visit(v); EnQueue(Q, v); //访问v,并入队 while( !QueueEmpty(Q) )
{ //队不空时
i=LocateVex(G,v1); j=LocateVex(G,v2); G.arcs[i][j].adj=w ;//弧<v1,v2> 的权值 int LocateVex(MGraph G,char u) //若弧含有相关信息,则输入 { int i; if (IncInfo) Input ; for(*G.arcs[i][j].info) (i=0;i<G.vexnum;i++) if (G.vexs[i] = =u) return i; G.arcs[j][i]=G.arcs[i][j] ; } //置<v1,v2>的对称弧<v2,v1>
(2)仔细分析实验内容,给出生成图和遍历图的算 法思想和算法流程图; (3)实现图的邻接矩阵、邻接表存储,并分别进行 深度和广度优先遍历; (4)给出测试数据,并分析其结果;
实验报告:图的存储结构和遍历
武汉东湖学院
实验报告
学院:计算机科学学院专业计算机科学与技术2016年11月18日
姓名付磊学号42
班级计科一班指导老师吴佳芬
课程名称数据结构成
绩
实验名称图的存储结构和遍历
1.实验目的
(1)了解邻接矩阵存储法和邻接表存储法的实现过程。
(2)了解图的深度优先遍历和广度优先遍历的实现过程。
2.实验内容
1. 采用图的邻接矩阵存储方法,实现下图的邻接矩阵存储,并输出该矩阵.
2. 设计一个将第1小题中的邻接矩阵转换为邻接表的算法,并设计一个在屏幕上显示邻接表的算法
3. 实现基于第2小题中邻接表的深度优先遍历算法,并输出遍历序列
4. 实现基于第2小题中邻接表的广度优先遍历算法,并输出遍历序列
3.实验环境
Visual C++ 6.0
4.实验方法和步骤(含设计)
我们通过二维数组中的值来表示图中节点与节点的关系。
通过上图可知,其邻接矩阵示意图为如下:
V0 v1 v2 v3 v4 v5
V0 0 1 0 1 0 1
V1 1 0 1 1 1 0
V2 0 1 0 0 1 0
V3 1 1 0 0 1 1
V4 0 1 1 1 0 0
V5 1 0 0 1 0 0
此时的“1”表示这两个节点有关系,“0”表示这两个节点无关系。
我们通过邻接表来在计算机中存储图时,其邻接表存储图如下:
}。
数据结构 无向图的存储和遍历
《数据结构》实验报告◎实验题目:无向图的存储和遍历◎实验目的:1、掌握使用Visual C++6.0上机调试程序的基本方法;2、掌握图的邻接表存储结构和深度优先遍历的非递归算法。
3、提高自己分析问题和解决问题的能力,在实践中理解教材上的理论。
◎实验内容:建立有10个顶点的无向图的邻接表存储结构,然后对其进行深度优先遍历,该无向图可以是无向连通图或无向非连通图。
一、需求分析1、输入的形式和输入值的范围:根据提示,首先输入图的所有边建立邻接表存储结构,然后输入遍历的起始顶点对图或非连通图的某一连通分量进行遍历。
2、输出的形式:输出对该图是连通图或非连通图的判断结果,若是非连通图则输出各连通分量的顶点,之后输出队连通图或非连通图的某一连通分量的遍历结果。
3、程序所能达到的功能:输入图的所有边后,建立图的邻接表存储结构,判断该图是连通图或非连通图,最后对图进行遍历。
4、测试数据:输入10个顶点(空格分隔):A B C D E F G H I J输入边的信息(格式为x y):AB AC AF CE BD DC HG GI IJ HJ EH该图为连通图,请输入遍历的起始顶点:A遍历结果为:A F C D B E H J I G是否继续?(是,输入1;否,输入0):1输入10个顶点(空格分隔):A B C D E F G H I J输入边的信息(格式为xy):AB AC CE CA AF HG HJ IJ IG该图为非连通图,各连通分量中的顶点为:< A F C E B > < D > < G I J H >输入第1个连通分量起始顶点:F第1个连通分量的遍历结果为:F A C E B输入第2个连通分量起始顶点:I第2个连通分量的遍历结果为:I G H J输入第3个连通分量起始顶点:D第3个连通分量的遍历结果为:D是否继续?(是,输入1;否,输入0):0谢谢使用!Press any key to continue二概要设计1、邻接表是图的一种顺序存储与链式存储结构结合的存储方法。
数据结构实验报告图的遍历
数据结构实验报告图的遍历数据结构实验报告:图的遍历引言在计算机科学中,图是一种重要的数据结构,它由节点和边组成,用于表示不同实体之间的关系。
图的遍历是一种重要的操作,它可以帮助我们了解图中节点之间的连接关系,以及找到特定节点的路径。
在本实验中,我们将讨论图的遍历算法,并通过实验验证其正确性和效率。
深度优先搜索(DFS)深度优先搜索是一种常用的图遍历算法,它通过递归或栈的方式来遍历图中的节点。
在实验中,我们实现了深度优先搜索算法,并对其进行了测试。
实验结果表明,深度优先搜索算法能够正确地遍历图中的所有节点,并找到指定节点的路径。
此外,我们还对算法的时间复杂度进行了分析,验证了其在不同规模图上的性能表现。
广度优先搜索(BFS)广度优先搜索是另一种常用的图遍历算法,它通过队列的方式来遍历图中的节点。
在实验中,我们也实现了广度优先搜索算法,并对其进行了测试。
实验结果显示,广度优先搜索算法同样能够正确地遍历图中的所有节点,并找到指定节点的路径。
我们还对算法的时间复杂度进行了分析,发现其在不同规模图上的性能表现与深度优先搜索算法相近。
实验结论通过本次实验,我们深入了解了图的遍历算法,并验证了其在不同规模图上的正确性和效率。
我们发现深度优先搜索和广度优先搜索算法都能够很好地应用于图的遍历操作,且在不同情况下都有良好的性能表现。
这些算法的实现和测试为我们进一步深入研究图的相关问题提供了重要的基础。
总结图的遍历是图算法中的重要操作,它为我们提供了了解图结构和节点之间关系的重要手段。
本次实验中,我们实现并测试了深度优先搜索和广度优先搜索算法,验证了它们的正确性和效率。
我们相信这些算法的研究和应用将为我们在图相关问题的研究中提供重要的帮助。
数据结构实验报告图的遍历讲解
数据结构试验报告实验四图的存储及应用实验题目:图的遍历问题专业班级:计科系1405班组长:张纪远(2014100518)组员:周振军(2014100551)朱新祥(2014100552)梁丽蓉(2014100526)段慧娟(2014100512)2016年 6月1日实验报告实验类型__综合设计__实验室_软件实验室三__一、实验题目图的存储及应用二、实验目的和要求1.掌握图的存储思想及其存储实现2.掌握图的深度、广度优先遍历算法思想及其程序实现3.掌握图的常见应用算法的思想及其程序实现三、需求分析1.问题描述使用菜单实现图的相关算法,如键盘输入以下结点数据:太原、成都、北京、上海、天津、大连、河北,建立一个有向图或无向图(自定)的邻接表并输出该邻接表;在图的邻接表的基础上计算各顶点的度,并输出;以有向图的邻接表为基础实现输出它的拓扑排序序列;采用邻接表存储实现无向图的深度优先遍历;采用邻接表存储实现无向图的广度优先遍历;采用邻接矩阵存储实现无向图的最小生成树的 PRIM 算法2.设计分析调用菜单项,分别调用相应的子函数。
注意顶点存储地名,使用字符数组来实现。
3.结构类型定义typedef char vextype[10];/*顶点数据类型*/typedef int edgetype;/*边数据类型*/typedef struct{vextype vex[MAXSIZE];edgetype arc[MAXSIZE][MAXSIZE];int vexnum,arcnum;}Mgraph;typedef struct node{int adjvex;struct node *next}EdgeNode;typedef struct node{vextype vex;EdgeNode * firstedge;}VexNode;typedef struct{VexNode adjvex[MAXSIZE];int n,e;}ALGraph;四、概要设计为了实现上述程序功能,代码如下:#include<stdio.h>#include<stdlib.h>#include<string.h>typedef struct node{//边表结点int adj;//边表结点数据域struct node *next;}node;typedef struct vnode{//顶点表结点char name[20];node *fnext;}vnode,AList[20];typedef struct{AList List;//邻接表int v,e;//顶点树和边数}*Graph;//建立无向邻接表Graph CreatDG(){Graph G;int i,j,k;node *s;G=malloc(20*sizeof(vnode));printf("请输入图的顶点数和边数(空格隔开):");scanf("%d%d",&G->v,&G->e);//读入顶点数和边数for(i=0;i<G->v;i++){printf("请输入图中第%d元素:",i+1);scanf("%s",G->List[i].name);//读入顶点信息G->List[i].fnext=NULL;//边表置为空表}for(k=0;k<G->e;k++){printf("请请输入第%d条边的两顶点序号(空格隔开):",k+1);scanf("%d%d",&i,&j);//读入边(Vi,Vj)的顶点对序号;s=(node *)malloc(sizeof(node));//生成边表结点s->adj=j;s->next=G->List[i].fnext;G->List[i].fnext=s;//将新结点*s插入顶点Vi的边表头部s=(node *)malloc(sizeof(node));s->adj=i;//邻接点序号为is->next=G->List[j].fnext;G->List[j].fnext=s;// 将新结点*s插入顶点Vj的边表头部}return G;}//有向邻接图Graph CreatAG(){Graph G;int i,j,k;node *q;G=malloc(20*sizeof(vnode));printf("请输入图的顶点数和边数【空格隔开】:");scanf("%d%d",&G->v,&G->e);for (i=0;i<G->v;i++){printf("请输入图中第%d元素:",i+1);scanf("%s",&G->List[i].name); //读入顶点信息G->List[i].fnext=NULL;}for (k=0;k<G->e;k++){printf("请请输入第%d边的两顶点序号【空格隔开】:",k+1);scanf("%d%d",&i,&j);q=(node *)malloc(sizeof(node)); //生成新边表结点sq->adj=j; //邻接点序号为jq->next=G->List[i].fnext;G->List[i].fnext=q;}return G;}//输出图的邻接表void Print(Graph G){int i;node *p;printf("\t=======邻接表========\n");for(i=0;i<G->v;i++){p=G->List[i].fnext;printf("%d | %3s",i,G->List[i].name);while(p){printf("->%3s",G->List[p->adj].name);printf("->%d",p->adj);p=p->next;}printf("\n");}}typedef struct {char vex[20];}Lists[20];typedef struct{Lists l;int edge[20][20];//邻接矩阵int v1,e1;//顶点数和弧数}AGraph;typedef struct{int data; /* 某顶点与已构造好的部分生成树的顶点之间权值最小的顶点 */ int lowcost; /* 某顶点与已构造好的部分生成树的顶点之间的最小权值 */ }ClosEdge[20]; /* 用普里姆算法求最小生成树时的辅助数组 */void CreateAN(AGraph *G1){/* 构造邻接矩阵结构的图G */int i,j,k,w;printf("请输入图的顶点数和边数(空格隔开):");scanf("%d%d",&G1->v1,&G1->e1);//读入顶点数和边数for(i=1;i<=G1->v1;i++){printf("请输入图%d号元素:",i);scanf("%s",&G1->l[i].vex);//读入顶点信息}for(i=1;i<=G1->v1;i++)//初始化邻接矩阵for(j=1;j<=G1->v1;j++)G1->edge[i][j] = 9;for(k=1;k<=G1->e1;k++){printf("请输入两顶点及边的权值(空格隔开):");scanf("%d%d%d",&i,&j,&w);G1->edge[i][j]=w;G1->edge[j][i]=w;}}void PrintAN(AGraph *G1){int i,j;printf("\t=======邻接矩阵========\n");for(i=1;i<=G1->v1;i++){for(j=1;j<=G1->v1;j++)printf("%3d",G1->edge[i][j]);printf("\n");}}//输出各顶点的度数void Du(Graph G){int i,j;node *p;printf("\n<----各点度数---->\n");for(i=0;i<G->v;i++){p=G->List[i].fnext;printf("顶点%2s的度为:",G->List[i].name);j=0;while(p){j++;p=p->next;}printf("%d\n",j);}}//栈typedef struct stack{int x;struct stack *next;}stack;int push(stack *s,int i){stack *p;p=(stack *)malloc(sizeof(stack));p->x=i;p->next=s->next;s->next=p;return 1;}int pop(stack *s,int j){stack *p=s->next;//保存栈顶指针j=p->x;s->next=p->next; //将栈顶元素摘下free(p);//释放栈顶空间return j;}//拓扑排序void Topo(Graph G,stack *s){int i,k, count;int j=0;int indegree[20]={0};node *p;for(i=0;i<G->v;i++){p=G->List[i].fnext;;while(p!=NULL){indegree[p->adj]++;p=p->next;}}for(i=0;i<G->v;i++)if(indegree[i]==0)push(s,i);count=0;while(s->next!=NULL){i=pop(s,j);printf("%2s ",G->List[i].name);++count;for(p=G->List[i].fnext;p!=NULL;p=p->next){ k=p->adj;if(!(--indegree[k]))push(s,k);}}if(count<G->v) printf("有回路!");}void DFS(Graph G,int i,int flag[]){node *p;printf("%2s ",G->List[i].name);flag[i]=1;p=G->List[i].fnext;while(p){if(!flag[p->adj])DFS(G,p->adj,flag);p=p->next;}}//深度优先遍历void DFSTravel(Graph G){int i;int flag[20];//标志数组for(i=0;i<G->v;i++)flag[i]=0;for(i=0;i<G->v;i++)if(!flag[i])DFS(G,i,flag);}//建立队列typedef struct{int *elem;int front, rear;}*Queue;//队列初始化void InitQueue(Queue Q){Q->elem=(int *)malloc(20*sizeof(int));if(!Q->elem)exit(0);Q->front=Q->rear=0;}//入队void Enter(Queue Q, int e){if((Q->rear + 1)%20!= Q->front)Q->elem[Q->rear ]=e;elseprintf("队列满!\n");Q->rear=(Q->rear+1)%20;}//出队void Leave(Queue Q, int e){if(Q->rear != Q->front)e=Q->elem[Q->front];elseprintf("队列空!\n");Q->front=(Q->front+1)%20;}//广度优先遍历void BFSTravel(Graph G){Queue Q;node *p;int i,j=0;int flag[20];//标志数组Q=malloc(sizeof(20));InitQueue(Q);for(i=0;i<G->v;i++)flag[i]=0;for(i=0;i<G->v;i++)if(flag[i]==0){flag[i]=1;printf("%2s",G->List[i].name);Enter(Q,i);while(Q->front!=Q->rear){Leave(Q,j);//队头元素出队并置为jp=G->List[j].fnext;while(p!=NULL){if(flag[p->adj]==0){printf("%2s ",G->List[p->adj].name);flag[p->adj]=1;Enter(Q,p->adj);}p=p->next;}}}}int minimum(ClosEdge cl,int vnum){int i;int w,p;w=1000;for(i=1;i<=vnum;i++)if(cl[i].lowcost!=0&&cl[i].lowcost<w){w=cl[i].lowcost;p=i;}return p;}void Prim(AGraph *G1,int u){ClosEdge closedge;int i,j,k;for(j=1;j<=G1->v1;j++) /* 辅助数组初始化 */if(j!=u){closedge[j].data=u;closedge[j].lowcost=G1->edge[u][j];}closedge[u].lowcost=0; /* 初始,U={u} */for(i=1;i<G1->v1;i++){k=minimum(closedge,G1->v1); /* 求出生成树的下一个顶点 */printf("%d-----%d\n",closedge[k].data,k); /* 输出生成树的边 */closedge[k].lowcost=0; /* 第k顶点并入U集 */for(j=1;j<=G1->v1;j++) /* 新顶点并入U后,修改辅助数组*/if(G1->edge[k][j]<closedge[j].lowcost){closedge[j].data=k;closedge[j].lowcost=G1->edge[k][j];}}}//菜单列表void menu(){printf("\t**********************图的遍历问题**********************\n");printf("\t\t------- 1.建立无向邻接图 ---------\n");printf("\t\t------- 2.建立有向邻接图 ---------\n");printf("\t\t------- 3.建立无向邻接矩阵 ---------\n");printf("\t\t------- 4.输出各顶点的度 ---------\n");printf("\t\t------- 5.拓扑排序 ---------\n");printf("\t\t------- 6.深度优先遍历 ---------\n");printf("\t\t------- 7.广度优先遍历 ---------\n");printf("\t\t------- 8.prim算法生成最小生成树---------\n");printf("\t\t------- 9-退出 ---------\n");printf("\t********************************************************\n"); }//主函数void main(){Graph G;AGraph G1;int choice,u;stack *s=(stack *)malloc(sizeof(stack));s->next =NULL;while(1){menu();printf("请输入选择:");scanf("%d",&choice);switch(choice){case 1:G=CreatDG();Print(G);printf("\n\n");break;case 2:G=CreatAG();Print(G);printf("\n\n");break;case 3:CreateAN(&G1);PrintAN(&G1);printf("\n\n");break;case 4:Du(G);printf("\n\n");break;case 5:printf("拓扑排序:");Topo(G,s);printf("\n\n");break;case 6:printf("深度优先遍历:");DFSTravel(G);printf("\n\n");break;case 7:printf("广度优先遍历:");BFSTravel(G);printf("\n\n");break;case 8:printf("请输入起点序号:");scanf("%d",&u);printf("Prim算法:\n");Prim(&G1,u);printf("\n");break;case 9: exit(0);default: printf("输入错误,请重新输入:\n\n ");}}}五、使用说明1、程序名为实验图的遍历.exe,运行坏境为VC6.0.程序执行后显示如图所示:2、建立无向邻接图3、输出各顶点的度4、进行深度优先遍历5、进行广度优先遍历6、建立有向邻接图7、拓扑排序8、建立无向邻接矩阵9、prim算法生成最小生成树八、实验总结通过对本次试验的学习,使我们明白了合作分工的重要性,这并不是一个容易的过程,中间碰到了许多问题,但我们都一一解决,有关于图这部分的内容很复杂,但是却非常重要,掌握好图的遍历有助于我们提升今后解决实际问题的能力,对我们非常有帮助。
数据结构图的遍历实验报告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");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)调试过程中主要遇到哪些问题?是如何解决的?由于实习之初对邻接表的存储结构了解不是很清楚,所以在运行出了一个小错误,即在输出邻接表时,每个结点都少了一个邻接点。
【结构】数据结构课程设计图的存储与遍历
【关键字】结构中南大学《数据结构》课程设计题目图的保存和遍历学生姓名指导教师学院信息科学与工程专业班级完成时间第一章课程设计目的1.1掌握图的邻接表存贮结构。
1.2掌握队列的基本运算实现。
1.3掌握图的邻接表的算法实现。
1.4掌握图的广度优先搜索周游算法实现。
1.5掌握图的深度优先搜索周游算法实现第二章设计内容和要求对任意给定的图(顶点数和边数自定),建立它的邻接表并输出,然后利用队列的五种基本运算(置空队列、进队、出队、取队头元素、判队空)实现图的广度、深度优先搜索周游。
第三章运行环境Turber c/c++集成实验与学习环境第四章课程设计分析我的设计思路是,先通过给定的顶点和边的信息构造出图,用邻接表保存该图,然后用DFS或BFS进行遍历.下面是我设计过程的结构图:图4.1 设计过程的结构图通过自己对图的保存与遍历的算法了解和实践,进一步加深了图的邻接表保存,其特点有:1.保存表示,不惟一,各边表结点的链接次序取决于建立邻接表的算法和边的输入次序;空间复杂度S(n,e) ,S(n,e)=O(n+e)。
稀疏图用邻接表表示比用邻接矩阵表示节省保存空间;2.求顶点的度,无向图:顶点vi的度则是第i个边表中的结点个数;3.判定(Vi,Vj)或<Vi,Vj>是否是图的一条边;在邻接表表示中,需扫描第i个边表最坏情况下要耗费O(n)时间;4.求边的数目,与e的大小无关只要对每个边表的结点个数计数即可求得e,所耗费的时间,是O(e+n)。
当e≤n2时,采用邻接表表示更节省空间。
至于两种遍历,在计算机科学中,经常会遇到图的遍历问题。
解决这一问题的经典算法就是所谓深度优先搜索和广度优先搜索,理论证明两套算法的性能是等效的。
遍历图的过程实质是通过边或弧找邻接点的过程,因此广度优先搜索遍历图的时间复杂度和深度优先搜索遍历相同,两者不同之处在于对顶点访问的顺序不同而已.第五章算法(数据结构)描述实现图的保存和遍历其思路总体分二个大步骤:1.1图的保存采用邻接表对图进行保存,并输出保存结果,为实现邻接表的建立附设连个指向图相关边的指针*p,*q.再用for(k=1;k<=e;k++)同时*p,*q移动,给每条边分配内存,再利用函数print(g,n)将建立好的邻接表输出。
实验报告:图的存储结构和遍历
武汉东湖学院
实验报告
学院:计算机科学学院专业计算机科学与技术2016年11月18日
姓名付磊学号2015040131042
班级计科一班指导老师吴佳芬
课程名称数据结构成
绩
实验名称图的存储结构和遍历
1.实验目的
(1)了解邻接矩阵存储法和邻接表存储法的实现过程。
(2)了解图的深度优先遍历和广度优先遍历的实现过程。
2.实验内容
1. 采用图的邻接矩阵存储方法,实现下图的邻接矩阵存储,并输出该矩阵.
2. 设计一个将第1小题中的邻接矩阵转换为邻接表的算法,并设计一个在屏幕上显示邻接表的算法
3. 实现基于第2小题中邻接表的深度优先遍历算法,并输出遍历序列
4. 实现基于第2小题中邻接表的广度优先遍历算法,并输出遍历序列
3.实验环境
Visual C++ 6.0
4.实验方法和步骤(含设计)
我们通过二维数组中的值来表示图中节点与节点的关系。
通过上图可知,其邻接矩阵示意图为如下:
V0 v1 v2 v3 v4 v5
V0 0 1 0 1 0 1
V1 1 0 1 1 1 0
V2 0 1 0 0 1 0
V3 1 1 0 0 1 1
V4 0 1 1 1 0 0
V5 1 0 0 1 0 0
此时的“1”表示这两个节点有关系,“0”表示这两个节点无关系。
我们通过邻接表来在计算机中存储图时,其邻接表存储图如下:
}。
图的存储实验报告
图的存储实验报告图的存储实验报告引言在计算机科学领域中,图是一种重要的数据结构,用于描述对象之间的关系。
图的存储方式对于图的遍历、搜索和其他操作有着重要的影响。
本实验旨在探究不同的图存储方式,并比较它们在不同操作下的性能差异。
一、邻接矩阵存储方式邻接矩阵是一种常见的图存储方式,它使用二维数组来表示图中各个顶点之间的关系。
在邻接矩阵中,行和列分别代表图中的顶点,矩阵中的元素表示两个顶点之间的边的关系。
实验中,我们通过一个简单的例子来说明邻接矩阵的存储方式。
假设有一个无向图,其中包含5个顶点和6条边。
我们可以使用一个5x5的矩阵来表示这个图,矩阵中的元素为1表示两个顶点之间存在边,为0表示不存在边。
邻接矩阵的优点是可以快速判断两个顶点之间是否存在边,时间复杂度为O(1)。
然而,邻接矩阵的缺点是当图中的边数较少时,会造成存储空间的浪费。
此外,在图中顶点的增加和删除操作时,需要重新调整矩阵的大小,开销较大。
二、邻接表存储方式邻接表是另一种常见的图存储方式,它使用链表来表示图中各个顶点之间的关系。
在邻接表中,每个顶点都有一个链表,链表中存储了与该顶点相邻的顶点。
实验中,我们同样以一个简单的例子来说明邻接表的存储方式。
假设有一个有向图,其中包含4个顶点和5条边。
我们可以使用一个包含4个链表的数组来表示这个图,数组中的每个元素表示一个顶点,链表中的元素表示与该顶点相邻的顶点。
邻接表的优点是在图中边的数量较少时,可以节省存储空间。
此外,在图中顶点的增加和删除操作时,开销较小。
然而,邻接表的缺点是判断两个顶点之间是否存在边的时间复杂度较高,需要遍历链表,时间复杂度为O(顶点的度数)。
三、性能比较与结论通过实验,我们对比了邻接矩阵和邻接表两种图存储方式在不同操作下的性能差异。
在判断两个顶点之间是否存在边的操作中,邻接矩阵的时间复杂度为O(1),而邻接表的时间复杂度为O(顶点的度数)。
因此,在此操作下,邻接矩阵的性能更优。
图的存储与遍历报告册
三、基本思想、原理和算法描述:
邻接矩阵:
printf("please input the vexnum,arcnum and arcs of graph:\n");
(1)问题描述:以邻接矩阵为图的存储结构,实现图的DFS和BFS遍历。
(2)基本要求:建立一个图的邻接矩阵表示,输出顶点的一种DFS和BFS序列。
题目2对以邻接表为存储结构的图进行DFS和BFS遍历
(1)问题描述:以邻接表为存储结构,实现图的DFS和BFS遍历。
(2)基本要求:建立一个图的邻接表存储,输出顶点的一种DFS和BFS序列。
}
四、源程序清单:见附页
五、程序运行结果(包括上机调试的情况、调试所遇到的问题是如何解决的,并对调试过程中的问题进行分析,对执行结果进行分析。):
1、二维矩阵的输入不确定。
2、没有考虑到多个起点的遍历,总是将一些顶点漏掉。
3、对链表的图各种内省成分还不太熟悉。
4、调试结果可见,在程序存在一定的问题,主要是会导致结点可能会重复输出,但如果改变起始点,运行结果又正常,关键问题还是没能找到问题的所在,但会进一步研究,修改程序使其能正常工作。
指导教师签名:2014年月日
DFS(G,i);
voidDFS(graph &G,intv)
{
intw,i;
visited[v]=true;
printf("%d",v+1);
for(w=0;w<G.vexnum;w++)
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
数据结构课程实验报告学号:: 实验日期:2016.1.7 实验名称: 图的存贮与遍历一、实验目的掌握图这种复杂的非线性结构的邻接矩阵和邻接表的存储表示, 以及在此两 种常用存储方式下深度优先遍历(DFS 和广度优先遍历(BFS 操作的实现。
、实验内容与实验步骤 题目1:对以邻接矩阵为存储结构的图进行 DFS 和BFS 遍历问题描述:以邻接矩阵为图的存储结构,实现图的 DFS 和BFS 遍历。
基本要求:建立一个图的邻接矩阵表示,输出顶点的一种DFS 和BFS 序列测试数据:如图所示0 10 0 01 0 0 0 1A 0 10 101 0 0 0 00 0 0 1 0题目2:对以邻接表为存储结构的图进行 DFS 和BFS 遍历问题描述:以邻接表为图的存储结构,实现图的 DFS 和BFS 遍历。
基本要求:建立一个图的邻接表存贮,输出顶点的一种 DFS 和BFS 序列 测试数据:如图所示在此贴上调试好的程序#i nclude<stdio.h>#i nclude<malloc.h>#i ncludevstri ng.h>V0 V1V2 V3 V41 A 0 14A3 A 0 A3A#define M 100typedef struct node{char vex[M][2];int edge[M ][ M ];int n ,e;}Graph;in t visited[M];Graph *Create_Graph(){ Graph *GA;int i,j,k,w;GA=(Graph*)malloc(sizeof(Graph));printf ("请输入矩阵的顶点数和边数(用逗号隔开):\n");sca nf("%d,%d", &GA-> n,&GA->e);printf ("请输入矩阵顶点信息:\n");for(i = 0;i<GA-> n;i++)scan f("%s",&(GA->vex[i][0]),&(GA->vex[i][1]));for (i = 0;i<GA-> n;i++)for (j = 0;j<GA-> n;j++) GA->edge[i][j] = 0;for (k = 0;k<GA->e;k++){ printf ("请输入第%4条边的顶点位置(i,j)和权值(用逗号隔开): ",k+1);sca nf ("%d,%d,%d",&i,&j, &w);GA->edge[i][j] = w;}return(GA);}void dfs(Graph *GA, i nt v){ int i;prin tf("%c%c\n",GA->vex[v][0],GA->vex[v][1]);visited[v]=1;for(i=0; i<GA->n; i++)if (GA->edge[v][i]==1 && visited[i]==0) dfs(GA, i);}void traver(Graph *GA){ int i;for(i=0; i<GA->n; i++)visited[i]=0;for(i=0; i<GA-> n;i++)if(visited[i]==0) dfs(GA, i);}void bfs( Graph *GA, i nt v){ int j,k,fro nt=-1,rear=-1;int Q[M];prin tf("%c%c\n",GA->vex[v][0],GA->vex[v][1]); visited[v]=1;rear=rear+1;Q[rear]=v;while (fron t!=rear){ fron t=fro nt+1;k=Q[fro nt];for (j=0; j<GA- >n; j++)if (GA->edge[k][j]==1 && visited[j]==0){ prin tf("%c%c\n",GA->vex[j][0],GA->vex[j][1]); visited[j]=1;rear=rear+1;Q[rear]=j;}}}void traver1(Graph *GA){ int i;for (i=0; i<GA-> n;i++)visited[i]=0;for (i=0; i<GA->n; i++)if (visited[i]==0)bfs(GA, i);typedef struct NODE{ int adjvex;struct NODE *n ext;}ENode;typedef struct NODE1{ char vex[2];ENode *first;} VexNode;typedef struct FS1{VexNode GL[M];int bia n,top;}FS;FS *CreateGL(){ FS *kk=(FS *)malloc(sizeof(FS));int i,j,k;ENode *s;printf("请输入顶点数和边数(用逗号隔开):\n");sca nf("%d,%d",&kk->top, & kk->bia n);printf("请输入顶点信息:\n");for (i=0; i<kk->top; i++){ sca nf("%s",kk->GL[i].vex);kk->GL[i].first=NULL; }printf("请输入边的信息(i,j): \n");for (k=0;k<kk->bia n;k++){ sca nf("\n%d,%d",&i,&j);s =(ENode*)malloc(sizeof(ENode)); s->adjvex=j;s-> next=kk->GL[i].first;kk->GL[i].first =s;}return kk;void DFS(FS *kk, i nt v){ ENode *w; int i;prin tf("%s\n",kk->GL[v].vex); visited[v]=1;w=kk->GL[v].first ;while (w!=NULL){ i=w->adjvex;if (visited[i]==0)DFS(kk,i);w=w- >n ext;}}void TRAVER(FS *kk){ int i;for(i=0; i<kk->top;i++) visited[i]=0;for(i=0; i<kk->top; i++)if(visited[i]==0)DFS(kk, i);}void BFS(FS *kk, i nt v){ int Q[M], front=-1,rear=-1;ENode *w;int i, k;prin tf("%s\n",kk->GL[v].vex); visited[v]=1;rear=rear+1; Q[rear]=v; while (fron t!=rear){ fron t=fro nt+1; k=Q[fro nt]; w=kk->GL[k].first; while(w!=NULL) { i=w->adjvex;if( visited[i]==0){ visited[i]=1; printf("%s",kk->GL[i].vex); rear=rear+1;Q[rear]=i;}w=w- >n ext;}}}void TRAVER1(FS *kk){ int i;for(i=0; i<kk->top;i++) visited[i]=0;for(i=0; i <kk->top;i++)if(visited[i]==0)BFS(kk,i);}int mai n(){int i=0;Graph *p;FS *q;while(i=1){/*建立菜单*/char jz[30]={"1.创建邻接矩阵"};char jd[30]={"2.邻接矩阵DFS 遍历"};char jb[30]={"3.邻接矩阵BFS遍历"};char bg[30]={"4.创建邻接表"};char bd[30]={"5.邻接表DFS 遍历"};char bb[30]={"6.邻接表BFS遍历"};char tc[30]={"7.退出"};char mn[30]={"菜单"};int l=strle n(jd);int o=strle n(mn);int m,n;prin tf("\n");for(m=0;m<=(2*l-o)/2;m++)printf("");prin tf("%s",m n);for(m=0;m<=(2*l-o)/2;m++) printf("");prin tf("\n");for(m=0;m<=2*l;m++)*\n",jz,jd,jb,bg,bd,bb,tc); for(m=0;m<=2*l;m++)prin tf("*");prin tf("\n");/*选择功能*/printf("请输入所需功能序号:");sca nf("%d",&n); switch( n){case 1: p=Create_Graph();break;case 2: traver(p);break;case 3: traver1(p);break;case 4: q=CreateGL();break;case 5: TRAVER(q);break;case 6: TRAVER1(q);break;case 7: retur n 0; default:pri ntf("输入功能序号有误! \n");}}return 0; prin tf("*"); *\n* %sprin tf("\n");prin tf("* %s *\n* %s *\n* %s *\n* *\n* %s *\n* %s%s90iTJK四、运行结果:在此把运行结果从屏幕上拷下来贴在此L.甸建邻按矩阵2.邻捞矩阵UF 克直厉 空却長拒陋氏遍历 匸D.建邹接夫 匚卸接衷茁2遍历□ XO E :\Cer necrrDXiIrtua ISyEtem\5 …esE V7 琴单V乗单 戌■:口:壮:(£* X K 相fc 宜 宅 gc X 童扫4c 址** # * We* 3C : |C 电斗 >二輩 请输入所需功能序号,EVI莖单T •退岀淸输入肝需功盘序号;e 乩卸接夬ME 盘圧匚劭轄耒丽2凰⑷ +-4=4=水V1V4VJ VIV4 请输入边旳低唱(ij j' iki L r 01.42r 12r 3k ”i 3=*=+■++4= #+#4=^ 芈****4=*云■芈*+乂卅斗:芈世+立卡卄北* 育输入所需功耕号;4 请输入顶做和边數:用逗号隔开h5 7 淸输入顶点信旦,了•退出测试数据要注意现实中矩阵是从1开始,而数组里是从0开始。