图的邻接表存储结构实验报告
图的存储结构与遍历 数据结构实验

实验报告June 11 2015姓名:陈斌学号:E11314079 专业:13计算机科学与技术数据结构第七次实验学号E11314079专业计算机科学与技术姓名陈斌实验日期2015.06.11教师签字成绩实验报告【实验名称】图的存储结构与遍历【实验目的】(1)掌握图的相关概念;(2)掌握图的存储结构;(3)掌握图的遍历算法并编程实现。
【实验内容】编写一个程序,实现图的相关运算,并在此基础上设计一个主程序,完成如下功能:(1)建立如教材图7.9所示的有向图G的邻接矩阵,并分别输出顶点表和邻接矩阵。
(2)由有向图G的邻接矩阵产生邻接表,并依次输出每一顶点和其邻接表。
(3)再由(2)的邻接表产生对应的邻接矩阵,并输出该矩阵。
(4)在图G的邻接矩阵存储表示基础上,输出从顶点V1开始的深度优先遍历序列(递归算法)。
(5)在图G的邻接表存储表示基础上,输出从顶点V1开始的广度优先遍历序列。
(6)利用非递归算法重解任务(4)(选做)。
源代码:head.h:#include<string.h>#include<ctype.h>#include<malloc.h> //malloc( )#include<limits.h> // INT ,MAX#include<stdio.h> //EOF,NULL#include<stdlib.h> //atoi( )#include<io.h> //eof( )#include<math.h> //floor( ),ceil( ),abs( )#include<process.h> //exit( )#include<iostream.h> //cout,cin//函数结果状态代码#define TRUE 1#define FALSE 0#define OK 1#define ERROR 0#define INFEASIBLE -1//OVERFLOW 在math.h中已定义为3typedefint Status;typedefint Boolean; // 布尔类型main.cpp:#include"head.h"#define MAX_NAME 5 /* 顶点字符串的最大长度+1 */#define MAX_INFO 20 /* 相关信息字符串的最大长度+1 */typedefintVRType;typedefintInfoType;typedef char VertexType[MAX_NAME];#define INFINITY INT_MAX /* 用整型最大值代替∞*/#define MAX_VERTEX_NUM 20 /* 最大顶点个数*/typedefenum{DG,DN,AG,AN}GraphKind; /* {有向图,有向网,无向图,无向网} *//*图的数组(邻接矩阵)存储表示*/typedefstruct{VRTypeadj; /* 顶点关系类型。
图的邻接表存储结构实验报告

《图的邻接表存储结构实验报告》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.会用图的遍历解决简单的实际问题。
二、实验内容[题目一] :从键盘上输入图的顶点和边的信息,建立图的邻接表存储结构,然后以深度优先搜索和广度优先搜索遍历该图,并输出起对应的遍历序列. 试设计程序实现上述图的类型定义和基本操作,完成上述功能。
该程序包括图类型以及每一种操作的具体的函数定义和主函数。
[题目二]:在图G中求一条从顶点 i 到顶点 s 的简单路径设计要求:1、上机前,认真学习教材,熟练掌握图的构造和遍历算法,图的存储结构也可使用邻接矩阵等其他结构.2、上机前,认真独立地写出本次程序清单,流程图。
图的构造和遍历算法分别参阅讲义和参考教材事例三、实验步骤㈠、数据结构与核心算法的设计描述#define MAX_VERTEX_NUM 20//变量声明typedef struct ArcNode//弧结点定义{int adjvex; //该弧所指向的顶点的位置struct ArcNode *nextarc;//指向下一条弧的指针//InfoType *info;}ArcNode;typedef struct VNode//顶点结点定义{char data; //顶点信息ArcNode *firstarc; //指向第一条依附该顶点的弧的指针}VNode,AdjList[MAX_VERTEX_NUM];typedef struct//图的定义{AdjList vertices;int vexnum,arcnum; //图的当前顶点数和弧数int kind; //图的种类标志}ALGraph;ALGraph G; //定义图变量bool visited[MAX_VERTEX_NUM]; //访问标志数组typedef struct QueueNode//队列结点类型定义{int data; //结点中所存值QueueNode *next; //指向下一个结点}QueueNode;typedef struct//队列定义{QueueNode *first; //队列的头指针QueueNode *rear; //队列的尾指针}QueueLink;相关函数声明:void CreateGraph(MGraph &G)// 输入图的顶点和边的信息,建立图void DFSTraverse(Graph G, int v)//深度优先搜索遍历图void BFSTraverse(Graph G, int v)//广度优先搜索遍历图int LocateVertices(ALGraph G,char a)//查找字符a在图中的位置int FirstAdjVex(ALGraph G,int v)//查找图中位置v的第一个邻接点在图中所在的位置int NextAdjVex(ALGraph G,int v,int w)//查找相对于图中位置v的邻接点w的下一邻接点在图中的位置void DestroyGraph(ALGraph &G)//销毁图void DFS(ALGraph G,int v)//利用递归实现对图中一个极大强连通分量的遍历void DFSTraverse(ALGraph G)//深度遍历访问图void InitQueue(QueueLink &Queue)//初始化队列void EnQueue(QueueLink &Queue,int i)//元素i入队列void DeQueue(QueueLink &Queue,int &i)//队列头元素出队int QueueEmpty(QueueLink Queue)//判断队列是否为空,若为空则返回1,否则返回0void DestroyQueue(QueueLink &Queue)//销毁队列void BFSTraverse(ALGraph G)//利用队列实现图的广度优先遍历㈢程序调试及运行结果分析在调试过程中,LocateVertices(ALGraph G,char a)函数中少了一个return -1语句,经过修改得到正确的结果。
实验六 图的邻接表存储及遍历

}
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、在主函数中调用上述操作函数。
要求给出至少两组测试数据。
选做部分基于邻接表存储结构实现图的广度优先搜索算法。
数据结构实验报告

数据结构实验报告(实验五&&实验六)班级:软件121学号:201200834122姓名:程猛实验五图的基本操作1.问题描述:以邻接表为存储结构,实现连通无向图的深度优先和广度优先遍历。
以用户指定的结点为起点,分别输出每种遍历下的结点访问序列。
2.算法设计:以邻接表存储图的结构,建立一个图的类,并且用数组visited[i]标记该节点是否被访问。
并由临接表建立邻接矩阵。
再由输入的k值确定访问的起始点。
报错机制,当输入的数据,不符合要求时,会提醒。
3.测试数据:图的点数:5图的总边数:5边的起点和终点序号:1 2 2 3 3 4 4 04.源代码:#include"stdafx.h"#include<iostream>#include<iomanip>using namespace std;#include<stdlib.h>const int MaxV=10;//最多顶点数//定义邻接表中的边节点类型struct edgenode{int adjvex; //邻接点域edgenode* next;//指向下一个边节点的链域};//定义邻接表的类型typedef edgenode** adjlist;//邻接矩阵类的定义class AdjMatrix{private:char g[MaxV]; //顶点信息数组int size; //当前顶点数int GA[MaxV][MaxV];//定义邻接矩阵GAint numE;//当前边数public://构造函数,初始化图的邻接矩阵AdjMatrix(int n);//判断图空否bool GraphEmpty() {return size==0;}//取当前顶点数int NumV() {return size;}//取当前边数int NumEdges() {return numE;}//取顶点i的值char GetValue(const int i);//取弧<v1,v2>的权int GetWeight(const int v1,const int v2);//在位置pos处插入顶点vvoid InsertV(const char &V,int pos);//插入弧<v1,v2>权为weightvoid InsertEdge(const int v1,const int v2,int weight);//建立弧的邻接矩阵void CreateMatrix(int n);//k1为则无向否则为有向k2为则有权,否则无权//从初始点vi出发深度优先搜索由邻接矩阵表示的图void dfsMatrix(bool * &visited,int i,int n);//从初始点vi出发广度优先搜索由邻接矩阵表示的图void bfsMatrix(bool * &visited,int i,int n);//由图的邻接矩阵的到图的邻接表void graphChange(adjlist &GL,int n);//检查输入的边序号是否越界,否则重新输入void check(int n,int & i,int & j);//由图的邻接矩阵建立图void Creategraph(int n);//对非连通图进行深度优先搜索void dfsMatrix(int n);//对非连通图进行广度优先搜索void bfsMatrix(int n);};AdjMatrix::AdjMatrix(int n){int i,j;for(i=0;i<n;i++)for(j=0;j<n;j++)GA[i][j]=0;size=numE=0;}//建立图的邻接矩阵void AdjMatrix::CreateMatrix(int n){int i,j,k,e;cout<<"输入图的总边数:";cin>>e;cout<<"输入"<<e<<"条无向无权边的起点和终点序号:"<<endl;for(k=1;k<=e;k++){cin>>i>>j;check(n,i,j);GA[i][j]=GA[j][i]=1;}numE=e;cout<<"创建后的邻接矩阵:"<<endl;for(i=0;i<n;i++){for(j=0;j<n;j++)cout<<setw(4)<<GA[i][j];cout<<endl;}}void AdjMatrix::dfsMatrix(bool*& visited,int i,int n){cout<<g[i]<<':'<<i<<" ";visited[i]=true;for(int j=0;j<n;j++)if(i!=j&&GA[i][j]!=0&&!visited[j])dfsMatrix(visited,j,n);}void AdjMatrix::bfsMatrix(bool*& visited,int i,int n){const int MaxLength=30;int q[MaxLength]={0};int front=0,rear=0;cout<<g[i]<<':'<<i<<" ";visited[i]=true;q[++rear]=i;while(front!=rear){front=(front+1)%MaxLength;int k=q[front];for(int j=0;j<n;j++)if(k!=j&&GA[k][j]!=0&&!visited[j]){cout<<g[j]<<':'<<j<<" ";visited[j]=true;rear=(rear+1)%MaxLength;q[rear]=j;}}}void AdjMatrix::check(int n,int& i,int& j){while(1){if(i<0||i>=n||j<0||j>=n)cout<<"输入有误,请重输!";elsereturn;cin>>i>>j;}}void AdjMatrix::graphChange(adjlist &GL,int n) {int i,j;for(i=0;i<n;i++){for(j=0;j<n;j++)if(GA[i][j]!=0){edgenode*p=new edgenode;p->adjvex=j;p->next=GL[i];GL[i]=p;cout<<'('<<i<<','<<p->adjvex<<") ";}cout<<endl;}}void AdjMatrix::Creategraph(int n){int i,j,k,m=0;for(i=0;i<n;i++){k=i;for(j=0;j<n;j++)if(GA[i][j]!=0)if(k==i&&m<n){g[m]='A'+m;size++;cout<<g[m]<<'('<<i<<','<<j<<") ";m++;}}cout<<endl;g[n]='\0';}char AdjMatrix::GetValue(const int i){if(i<0||i>size){cerr<<"参数i越界"<<endl;exit(1);}return g[i];}int AdjMatrix::GetWeight(const int v1,const int v2) {if(v1<0||v1>size||v2<0||v2>size){cerr<<"参数v1或v2越界!"<<endl;exit(1);}return GA[v1][v2];}void AdjMatrix::InsertV(const char &V,int pos){int i;if(size==MaxV){cerr<<"表已满,无法插入!"<<endl;exit(1);}if(pos<0||pos>size){cerr<<"参数pos越界!"<<endl;exit(1);}for(i=size;i>pos;i--)g[i]=g[i-1];g[pos]=V;size++;}void AdjMatrix::InsertEdge(const int v1,const int v2,int weight) {if(v1<0||v1>size||v2<0||v2>size){cerr<<"参数v1或v2越界"<<endl;exit(1);}GA[v1][v2]=weight;numE++;}void AdjMatrix::dfsMatrix(int n){int i;bool *vis=new bool[NumV()];for( i=0;i<NumV();i++)vis[i]=false;for(i=0;i<NumV();i++)if(!vis[i])dfsMatrix(vis,i,n);delete []vis;}void AdjMatrix::bfsMatrix(int n){int i;bool *vis=new bool[NumV()];for( i=0;i<NumV();i++)vis[i]=false;for(i=0;i<NumV();i++)if(!vis[i])bfsMatrix(vis,i,n);delete []vis;}int _tmain(int argc, _TCHAR* argv[]) {int n,k,i;bool *vis;adjlist Al;cout<<"输入图的点数n=";cin>>n;Al=new edgenode*[n];vis=new bool[n];if(!vis){cout<<"申请堆内存失败!"<<endl;exit(1);}for(i=0;i<n;i++){vis[i]=false;}AdjMatrix A(n);A.CreateMatrix(n);cout<<"出发点vk的序号=";cin>>k;cout<<endl<<"输出邻接矩阵相应图的顶点"<<endl;A.Creategraph(n);cout<<"图的深度优先搜索顺序:"<<endl;A.dfsMatrix(vis,k,n);for(i=0;i<n;i++)vis[i]=false;cout<<endl<<"图的广度优先搜索顺序:"<<endl;A.bfsMatrix(vis,k,n);cout<<endl<<"输出邻接表的每个邻接点"<<endl;for(i=0;i<n;i++)vis[i]=false;A.graphChange(Al,n);delete []vis;return 0;}5.结果和分析:图的点数序列从零开始。
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截图):四、心得体会。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
《图的邻接表存储结构实验报告》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 i;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中第一个邻接顶点的序号。
若顶点在G中没有邻接顶点//则返回-1node *p;int v1;v1=LocateVex(G,v);p=G->List[v1].fnext;if(p)return p->adj;elsereturn -1;}8)找到图结点v的第二个邻接顶点的序号void NextAdjVex(Graph G,char *v,char *w){//初始条件:图G存在,v是G中某个顶点,w是v得邻接点//操作结果:输出v的(相对于w的)下一个邻接点的序号node *p;int v1,w1;v1=LocateVex(G,v);w1=LocateVex(G,w);p=G->List[v1].fnext;while(p&&p->adj!=w1)p=p->next;if(!p||!p->next)printf("没有第二个邻接点!\n");elseprintf("第二个邻接点序号是:%d\n",p->next->adj);}9)深度优先遍历图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[M];//标志数组for(i=0;i<G->v;i++)flag[i]=0;for(i=0;i<G->v;i++)if(!flag[i])DFS(G,i,flag);}10)广度优先遍历void BFSTravel(Graph G)//广度优先遍历{ Queue Q;node *p;int i,j=0;int flag[M];//标志数组Q=malloc(sizeof(M));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);}//ifp=p->next;}//while}//while}//if}5.输入/输出数据1)选择操作2)选择“1”然后输入“3 3”输入“a”,“b”,“c”输入“0 1”,“1 2”,“2 0”3)选择“2”跟选择“1”类似4)选择“3”5)选择“4”输入“1”6)选择“5”输入“a”7)选择“6”8)选择“7”9)选择“0”退出程序6.总结此次实验要求熟练掌握关于图的各项基本操作,重点在利用邻接表存储图的结构,以及深度、广度优先遍历图的方法。