数据机构实验六 图的邻接表存储及遍历
实验六图的邻接表存储及遍历一、实验学时 2学时二、背景知识1.图的邻接表存储结构在图的邻接表中,图中每个顶点都建立一个单链表,第i个单链表中的结点数为顶点i的出度。
(逆邻接表中,第i个单链表中的结点数为顶点i的入度)邻接表的数据结构描述为:struct node{ int vertex;struct node *nextnode;};typedef struct node *graph;struct node head[vertexnum];2.图的遍历深度优先遍历(DFS)法:算法步骤:1)初始化:(1)置所有顶点“未访问”标志;(2)打印起始顶点;(3)置起始顶点“已访问”标志;(4)起始顶点进栈。
2)当栈非空时重复做:(1)取栈顶点;(2)如栈顶顶点存在被访问过的邻接顶点,则选择一个顶点做:①打印该顶点;②置顶点为“已访问”标志;③该顶点进栈;否则,当前栈顶顶点退栈。
3)结束。
广度优先遍历(BFS)法:算法步骤:1) 初始化:(1)置所有顶点“未访问”标志;(2)打印起始顶点;(3)置起始顶点“已访问”标志;(4)起始顶点入队。
2)当队列非空时重复做:(1)取队首顶点;(2)对与队首顶点邻接的所有未被访问的顶点依次做:①打印该顶点;②置顶点为“已访问”标志;③该顶点入队;否则,当前队首顶点出队。
3) 结束。
三、目的要求1.掌握图的基本存储方法;2.掌握有关图的操作算法并用高级语言实现;3.熟练掌握图的两种搜索路径的遍历方法。
四、实验内容1.编写程序实现下图的邻接表表示及其基础上的深度和广度优先遍历。
五、程序实例图的邻接表表示法的C语言描述:#include <stdlib.h>#include <stdio.h>struct node /* 图形顶点结构定义 */{int vertex; /* 顶点 */struct node *nextnode; /* 指下一顶点的指针 */};typedef struct node *graph; /* 图形的结构重定义 */struct node head[6]; /* 图形顶点结构数组 *//*----------建立图形--------*/void creategraph(int *node,int num){graph newnode; /* 新顶点指针 */graph ptr;int from; /* 边线的起点 */int to; /* 边线的终点 */int i;for ( i = 0; i < num; i++ ) /* 读取边线的回路 */{from = node[i*2]; /* 边线的起点 */to = node[i*2+1]; /* 边线的终点 *//* 申请存储新顶点的内存空间 */newnode = ( graph ) malloc(sizeof(struct node));newnode->vertex = to; /* 建立顶点内容 */newnode->nextnode = NULL; /* 设定指针初值 */ptr = &(head[from]); /* 顶点位置 */while ( ptr->nextnode != NULL ) /* 遍历至链表尾 */ptr = ptr->nextnode; /* 下一个顶点 */ptr->nextnode = newnode; /* 插入结尾 */}}/*------主程序: 建立图形后,将邻接链表输出------*/void main(){graph ptr;int node[12][2] = { {1, 2}, {2, 1}, /* 边线数组 */ {1, 3}, {3, 1},{2, 3}, {3, 2},{2, 4}, {4, 2},{3, 5}, {5, 3},{4, 5}, {5, 4} };int i;for ( i = 1; i <= 5; i++ ){head[i].vertex = i; /* 设定顶点值 */ head[i].nextnode = NULL; /* 清除图形指针 */ }creategraph(*node,12); /* 建立图形 */ printf("图形的邻接链表内容:\n");for ( i = 1; i <= 5; i++ ){printf("顶点%d =>",head[i].vertex);/* 顶点值 */ ptr = head[i].nextnode; /* 顶点位置 */ while ( ptr != NULL ) /* 遍历至链表尾 */ {printf(" %d ",ptr->vertex); /* 输出顶点内容 */ ptr = ptr->nextnode; /* 下一个顶点 */ }printf("\n"); /* 换行 */ }}深度和广度优先遍历#include<stdio.h>#include<conio.h>#include<stdlib.h>#define MAX_VERTEX_MUN 20int visited[20];typedef struct ArcNode{int adjvex;struct ArcNode *nextarc;char *info;}ArcNode;typedef struct VNode{char data;ArcNode *firstarc;}VNode,AdjList[20];typedef struct{AdjList vertices;int vexnum,arcnum;}ALGragh;typedef struct QNode{int data;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;}int EnQueue(LinkQueue &Q,int e){QueuePtr p;p=(QueuePtr)malloc(sizeof(QNode));if(!p)exit(0);p->next=NULL;p->data=e;Q.rear->next=p;Q.rear=p;return 1;}int DeQueue(LinkQueue &Q,int e){QueuePtr p;if(Q.front==Q.rear)exit(0);p=Q.front->next;e=p->data;Q.front->next=p->next;if(Q.rear==p)Q.rear=Q.front;free(p);return 1;}int EmptyQueue(LinkQueue Q){if(Q.front==Q.rear)return 1;return 0;}int LocateVex(ALGragh G,char v){ int i;for(i=0;i<G.vexnum;i++)if(v==G.vertices[i].data)return i;return -1;}int FirstAdjVex(ALGragh G,char v){ int i;ArcNode *p;i=LocateVex(G,v);if(i==-1)return -1;p=G.vertices[i].firstarc;if(p)return p->adjvex;elsereturn -1;}int NextAdjVex(ALGragh G,char v,char w) {int i,j;ArcNode *p,*q;i=LocateVex(G,v);j=LocateVex(G,w);if(i==-1||j==-1||i==j)return -1;p=G.vertices[i].firstarc;while(p->nextarc&&p->adjvex!=j)p=p->nextarc;if(p->nextarc){q=p->nextarc;return q->adjvex;}elsereturn -1;}int Visit(char v){printf("%c",v);return 1;}//构造无向图int CreateDG(ALGragh &G){int v,e,i,j,t;ArcNode *p,*q;char tail,head;printf("input the number of the vertices:");scanf("%d",&v);if(v<0)return 0;G.vexnum=v;printf("input the number of the arcs:");scanf("%d",&e);if(e<0)return 0;G.arcnum=e;printf("build the Dg G:\n");for(t=0;t<G.vexnum;t++){ fflush(stdin);printf("input the vertice %d 's information",t+1);scanf("%c",&G.vertices[t].data);G.vertices[t].firstarc=NULL;}for(t=0;t<G.arcnum;t++){fflush(stdin);printf("input v1 and v2 is information :tail-head");scanf("%c%*c%c",&tail,&head);i=LocateVex(G,tail);j=LocateVex(G,head);if(i==-1||j==-1||i==j)return 0;p=(ArcNode *)malloc(sizeof(ArcNode));p->adjvex=j;p->info=NULL;p->nextarc=NULL;if(!G.vertices[i].firstarc)G.vertices[i].firstarc=p;else{//for(q=G.vertices[i].firstarc;q->nextarc;q=q->nextarc);q->nextarc=p;}}return 1;}int BFSTraverse(ALGragh G,int(*Visit)(char v)){LinkQueue Q;int v,w,u;for(v=0;v<G.vexnum;v++)visited[v]=0;InitQueue(Q);for(v=0;v<G.vexnum;v++){if(!visited[v]){visited[v]=1;Visit(G.vertices[v].data);EnQueue(Q,v);while(!EmptyQueue(Q)){DeQueue(Q,u);for(w=FirstAdjVex(G,G.vertices[u].data);w>=0;w=NextAdjVex(G,G.vertices[u].data,G.vertices[w].data))if(!visited[w]){visited[w]=1;Visit(G.vertices[w].data);EnQueue(Q,w);}}}}return 1;}int DFS(ALGragh G,int v){int w;visited[v]=1;printf("%c",G.vertices[v].data);w=FirstAdjVex(G, G.vertices[v].data);for(;w>=0;w=NextAdjVex(G, G.vertices[v].data, G.vertices[w].data)) if(!visited[w])DFS(G,w);return 1;}int DFSTraverse(ALGragh G){int v;for(v=0;v<G.vexnum;v++)visited[v]=0;for(v=0;v<G.vexnum;v++)if(!visited[v])DFS(G,v);return 1;}void main(){ALGragh G;printf("create the DG G:\n");if(CreateDG(G)){printf("output the UDG G in DFS order:");DFSTraverse(G);printf("\n");printf("output the UDG G in BFS order:");BFSTraverse(G,Visit);printf("\n");}}。
【数据结构】图的存储和遍历实验报告
(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开始。
图的邻接表存储结构实验报告
《图的邻接表存储结构实验报告》1.需解决的的问题利用邻接表存储结果,设计一种图。
2.数据结构的定义typedef struct node{//边表结点int adj;//边表结点数据域struct node *next;}node;typedef struct vnode{//顶点表结点char name[20];node *fnext;}vnode,AList[M];typedef struct{AList List;//邻接表int v,e;//顶点树和边数}*Graph;3.程序的结构图4.函数的功能1)建立无向邻接表Graph Create1( )//建立无向邻接表{Graph G;int i,j,k;node *s;G=malloc(M*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++)//建立边表--建立了2倍边的结点{ printf("请输入边的两顶点序号:(从0考试)");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;}2)建立有向邻接图Graph Create2() //有向邻接图{Graph G;int i,j,k;node *q;G=malloc(M*sizeof(vnode));printf("请输入顶点数和弧数:");scanf("%d%d",&G->v,&G->e);for (i=0;i<G->v;i++) //建立有n个顶点的顶点表{ printf("请输入图第%d个元素:",i+1);scanf("%s",&G->List[i].name); //读入顶点信息G->List[i].fnext=NULL;}for (k=0;k<G->e;k++) //建立边表{ printf("请输入两顶点的序号:(从0开始)");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;}3)输出无向图的邻接表void Print1(Graph G)//输出无向图的邻接表{int i;node *p;printf("\n\t\t\t邻接表\n");for(i=0;i<G->v;i++){ p=G->List[i].fnext;printf("\t\t\t%d | %3s",i,G->List[i].name);while(p){printf("->%d",p->adj);p=p->next;}printf("\n");}}4)输出个元素的度数void Du(Graph G)//输出各元素的度数{int i,j;node *p;printf("\n\t\t\t各点度数\n");for(i=0;i<G->v;i++){ p=G->List[i].fnext;printf("\t\t\t顶点%2s的度为:",G->List[i].name);j=0;while(p){ j++;p=p->next;}printf("%d\n",j);}}5)返回图结点在的序号int LocateVex(Graph G,char *u){//初始条件:图G存在,u和G中顶点有相同的特征//操作结果:若G中存在顶点u,则返回该顶点在图中的位置;否则返回-1 int i;for(i=0;i<G->v;++i)if(strcmp(u,G->List[i].name)==0)return -1;}6)返回序号为v的图结点的值char *VertexGet(Graph G,int v){if(v>=G->v||v<0)exit(0);return G->List[v].name;}7)返回图结点v的第一个邻接顶点的序号int FirstAdjVex(Graph G,char *v){//初始条件:图G存在,v是G中的某个顶点//操作结果:返回v中第一个邻接顶点的序号。
数据结构实验报告-图的遍历
数据结构实验报告实验:图的遍历一、实验目的:1、理解并掌握图的逻辑结构和物理结构——邻接矩阵、邻接表2、掌握图的构造方法3、掌握图的邻接矩阵、邻接表存储方式下基本操作的实现算法4、掌握图的深度优先遍历和广度优先原理二、实验内容:1、输入顶点数、边数、每个顶点的值以及每一条边的信息,构造一个无向图G,并用邻接矩阵存储改图。
2、输入顶点数、边数、每个顶点的值以及每一条边的信息,构造一个无向图G,并用邻接表存储该图3、深度优先遍历第一步中构造的图G,输出得到的节点序列4、广度优先遍历第一部中构造的图G,输出得到的节点序列三、实验要求:1、无向图中的相关信息要从终端以正确的方式输入;2、具体的输入和输出格式不限;3、算法要具有较好的健壮性,对错误操作要做适当处理;4、程序算法作简短的文字注释。
四、程序实现及结果:1、邻接矩阵:#include <stdio.h>#include <malloc.h>#define VERTEX_MAX 30#define MAXSIZE 20typedef struct{intarcs[VERTEX_MAX][VERTEX_MAX] ;int vexnum,arcnum;} MGraph; void creat_MGraph1(MGraph *g) { int i,j,k;int n,m;printf("请输入顶点数和边数:");scanf("%d%d",&n,&m);g->vexnum=n;g->arcnum=m;for (i=0;i<n;i++)for (j=0;j<n;j++)g->arcs[i][j]=0;while(1){printf("请输入一条边的两个顶点:\n");scanf("%d%d",&i,&j);if(i==-1 || j==-1)break;else if(i==j || i>=n || j>=n){printf("输入错误,请重新输入!\n");}else{g->arcs[i][j]=1;g->arcs[j][i]=1;}}}void printMG(MGraph *g) {int i,j;for (i=0;i<g->vexnum;i++){for (j=0;j<g->vexnum;j++)printf(" %d",g->arcs[i][j]);printf("\n");}printf("\n");}main(){int i,j;int fg;MGraph *g1;g1=(MGraph*)malloc(sizeof(MGraph));printf("1:创建无向图的邻接矩阵\n\n");creat_MGraph1(g1);printf("\n此图的邻接矩阵为:\n"); printMG(g1);}2、邻接链表:#include<stdio.h>#include<malloc.h>#define MAX_SIZE 10typedef struct node{int vertex;struct node *next;}node,adjlist[MAX_SIZE];adjlist g;int visited[MAX_SIZE+1];int que[MAX_SIZE+1];void creat(){int n,e;int i;int start,end;node *p,*q,*pp,*qq;printf("输入无向图的顶点数和边数:");scanf("%d%d",&n,&e);for(i = 1; i <= n ; i++){visited[i] = 0;g[i].vertex = i;g[i].next = NULL;}printf("依次输入边:\n");for(i = 1; i <= e ; i++){scanf("%d%d",&start,&end);p=(node *)malloc(sizeof(node));p->vertex = end;p->next = NULL;q = &g[start];while(q->next)q = q->next;q->next = p;p1=(node*)malloc(sizeof(node));p1->vertex = start;p1->next = NULL;q1 = &g[end];while(qq->next)q1 = q1->next;q1->next = p1;}}void bfs(int vi){int front,rear,v;node *p;front =0;rear = 1;visited[vi] = 1;que[0] = vi;printf("%d ",vi);while(front != rear){v = que[front];p = g[v].next;while(p){if(!visited[p->vertex]){visited[p->vertex]= 1;printf("%d",p->vertex);que[rear++] = p->vertex;}p = p->next;}front++;}}int main(){creat();bfs(1);printf("\n");return 0;}五.实验心得与体会:(1)通过这次实验,使我基本上掌握了图的存储和遍历,让我弄清楚了如何用邻接矩阵和邻接链表对图进行存储(2)深度优先遍历和广度优先遍历都有着各自的优点,通过程序逐步调试,可以慢慢的理解这两种遍历方法的内涵和巧妙之处。
实验六 图的邻接表存储及遍历
}
printf("\n"); /* 换行 */
}
}
{
printf("顶点%d =>",head[i].vertex);/* 顶点值 */
ptr = head[i].nextnode; /* 顶点位置 */
while ( ptr != NULL ) /* 遍历至链表尾 */
{
printf(" %d ",ptr->vertex); /* 输出顶点内容 */
2)当队列非空时重复做:
(1)取பைடு நூலகம்首顶点;
(2)对与队首顶点邻接的所有未被访问的顶点依次做:
打印该顶点;
置顶点为“已访问”标志;
该顶点入队;
否则,当前队首顶点出队。
3) 结束。
三、目的要求
1.掌握图的基本存储方法;
2.掌握有关图的操作算法并用高级语言实现;
3.熟练掌握图的两种搜索路径的遍历方法。
四、实验内容
1.编写程序实现下图的邻接表表示及其基础上的深度和广度优先遍历。
五、程序实例
图的邻接表表示法的C语言描述:
#include <stdlib.h>
#include <stdio.h>
struct node /* 图形顶点结构定义 */
{
int vertex; /* 顶点 */
struct node *nextnode; /* 指下一顶点的指针 */
};
typedef struct node *graph;
struct node head[vertexnum];
数据结构课程实验(图的存储与遍历)
实验五图的存储与遍历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算法的实现思想与以邻接矩阵为存储结构的实现是一样的。
数据结构与算法-图的邻接表
数据结构与算法-图的邻接表实验报告课程: 数据结构与算法实验日期: 实验名称: 图的邻接表一、实验目的掌握图的邻接表的创建和遍历二、实验内容必做部分1、给出图的邻接表存储结构的类型定义。
2、设计并实现以邻接表的方式构造一个无向网的算法。
Status CreateUDN(ALGraph &G) 3、设计并实现无向网的输出算法,要求能显示顶点以及顶点之间的邻接关系(方式自定) 4、基于邻接表方式实现:a) int FirstAdjVex(ALGraph G,int v) //返回v的第一个邻接点的下标,若不存在,则返回-1 b) int NextAdjVex(ALGraph G,int v,int w) // 返回v相对于w的下一个邻接点,若不存在,则返回-15、基于邻接表存储结构实现图的深度优先搜索算法。
void DFSTraverse(ALGraph G)6、在主函数中调用上述操作函数。
要求给出至少两组测试数据。
选做部分基于邻接表存储结构实现图的广度优先搜索算法。
三、实验步骤必做部分1、给出图的邻接表存储结构的类型定义。
12、设计并实现以邻接表的方式构造一个无向网的算法。
Status CreateUDN(ALGraph &G)3、设计并实现无向网的输出算法,要求能显示顶点以及顶点之间的邻接关系(方式自定)24、基于邻接表方式实现:a) int FirstAdjVex(ALGraph G,int v) //返回v的第一个邻接点的下标,若不存在,则返回-1b) int NextAdjVex(ALGraph G,int v,int w) // 返回v相对于w的下一个邻接点,若不存在,则返回-135、基于邻接表存储结构实现图的深度优先搜索算法。
void DFSTraverse(ALGraph G)6、在主函数中调用上述操作函数。
要求给出至少两组测试数据。
选做部分基于邻接表存储结构实现图的广度优先搜索算法。
实验六 图及其应用
实验六图及其应用数据结构实验六图及其应用1、实验目的? 熟练掌握图的两种存储结构(邻接矩阵和邻接表)的表示方法 ? 掌握图的基本运算及应用? 加深对图的理解,逐步培养解决实际问题的编程能力2、实验内容:采用邻接表或邻接矩阵方式存储图,实现图的深度遍历和广度遍历;用广度优先搜索方法找出从一顶点到另一顶点边数最少的路径。
1.问题描述:利用邻接表存储结构,设计一种图(有向或无向),并能够对其进行如下操作:1) 创建一个可以随机确定结点数和弧(有向或无向)数的图; 2) 根据图结点的序号,得到该结点的值;3) 根据图结点的位置的第一个邻接顶点的序号,以及下一个邻接顶点的序号;4) 实现从第v 个顶点出发对图进行深度优先递归遍历; 5) 实现对图作深度优先遍历;6) 实现对图进行广度优先非递归遍历; 编写主程序,实现对各不同的算法调用。
2.实现要求:(以邻接表存储形式为例)编写图的基本操作函数::对图的各项操作一定要编写成为C(C++)语言函数,组合成模块化的形式,每个算法的实现要从时间复杂度和空间复杂度上进行评价。
1)“建立图的邻接表算法”:CreateGraph(ALGraph *G) 操作结果:采用邻接表存储结构,构造没有相关信息的图G2)“邻接表表示的图的递归深度优先遍历算法”:DFSTraverse(ALGraphG,void(*Visit)(char*)) 初始条件:图G 已经存在;操作结果:返回图的按深度遍历的结果。
3)“邻接表表示的图的广度优先遍历算法”: BFSTraverse(ALGraphG,void(*Visit)(char*)) 初始条件:图G 已经存在;操作结果:返回图的按广度遍历的结果。
4)“邻接表从某个结点开始的广度优先遍历算法”:BFS(ALGraph G, int v)初始条件:图G 已经存在;操作结果:返回图从某个结点开始的按广度遍历的结果。
分析: 修改输入数据,预期输出并验证输出的结果,加深对有关算法的理解。
实验报告:图的存储结构和遍历
武汉东湖学院
实验报告
学院:计算机科学学院专业计算机科学与技术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”表示这两个节点无关系。
我们通过邻接表来在计算机中存储图时,其邻接表存储图如下:
}。
