数据结构实验报告无向图邻接矩阵存储结构
天津理工大学数据结构实验报告4
附录(可包括源程序清单或其它说明)#include <stdio.h>#include <string>#define MAX_NAME 10#define MAX_INFO 80typedef char InfoType;typedef char V ertexType[MAX_NAME]; // 字符串类型#define MAX_VERTEX_NUM 20typedef enum{unvisited,visited}VisitIf;typedef struct EBox{VisitIf mark; // 访问标记int ivex,jvex; // 该边依附的两个顶点的位置struct EBox *ilink,*jlink; // 分别指向依附这两个顶点的下一条边InfoType *info; // 该边信息指针}EBox;typedef struct{V ertexType data;EBox *firstedge; // 指向第一条依附该顶点的边}V exBox;typedef struct{V exBox adjmulist[MAX_VERTEX_NUM];int vexnum,edgenum; // 无向图的当前顶点数和边数}AMLGraph;typedef int QElemType;typedef struct QNode{// 单链表的链式存储结构QElemType data; //数据域struct QNode *next; //指针域}QNode,*QueuePtr;typedef struct{QueuePtr front,//队头指针,指针域指向队头元素rear; //队尾指针,指向队尾元素}LinkQueue;// 若G中存在顶点u,则返回该顶点在无向图中位置;否则返回-1int LocateV ex(AMLGraph G,V ertexType u){int i;for(i=0;i<G.vexnum;++i)if(strcmp(u,G.adjmulist[i].data)==0)return i;return -1;}int CreateGraph(AMLGraph *G){ // 采用邻接表存储结构,构造无向图G int i,j,k,l,IncInfo;char s[MAX_INFO];V ertexType va,vb;EBox *p;printf("请输入无向图G的顶点数,边数: ");scanf("%d,%d",&(*G).vexnum,&(*G).edgenum);printf("请输入%d个顶点的值(<%d个字符):\n",(*G).vexnum,MAX_NAME);for(i=0;i<(*G).vexnum;++i){ // 构造顶点向量scanf("%s",(*G).adjmulist[i].data);(*G).adjmulist[i].firstedge=NULL;}printf("请顺序输入每条边的两个端点(以空格作为间隔):\n");for(k=0;k<(*G).edgenum;++k){// 构造表结点链表scanf("%s%s%*c",va,vb); // %*c吃掉回车符i=LocateV ex(*G,va); // 一端j=LocateV ex(*G,vb); // 另一端p=(EBox*)malloc(sizeof(EBox));p->mark=unvisited; // 设初值p->ivex=i;p->jvex=j;p->info=NULL;p->ilink=(*G).adjmulist[i].firstedge; // 插在表头(*G).adjmulist[i].firstedge=p;p->jlink=(*G).adjmulist[j].firstedge; // 插在表头(*G).adjmulist[j].firstedge=p;}return 1;}V ertexType* GetVex(AMLGraph G,int v){ // 返回v的值if(v>=G.vexnum||v<0)exit(0);return &G.adjmulist[v].data;}// 返回v的第一个邻接顶点的序号。
数据结构实验四报告
实验日期:_______________ 实验指导老师:
实验4 无向图的深度优先搜索
一、实验目的和实验环境
【实验目的】
1、了解图的定义、特点,区分无向图和有向图的概念;
2、了解图的数据结构和搜索方法;
3、掌握无向图的邻接矩阵、邻接表的表示方法;
4、写出无向图的深度优先搜索程序。
【实验环境】VC++6.0
二、理论依据
邻接多重表是无向图的一种很有效链式存储结构,在邻接表中容易求得顶点和边的各种信息。
除了在边结点中增加一个标志域外,邻接多重表所需的存储量和邻接表相同。
三、实验内容
设无向图G有n个点e条边,写一算法建立G的邻接多表,并按照深度优先搜索输出顶点,要求该算法时间复杂性为O(n+e),且除邻接多表本身所占空间之外只用O(1)辅助空间。
四、实验步骤
1、了解图的定义、特点,区分无向图和有向图的概念;
2、了解图的数据结构和搜索方法;
3、掌握无向图的邻接矩阵、邻接表的表示方法;
4、写出无向图的深度优先搜索程序
五、实验结果
1.源代码如下:
实验日期:_______________ 实验指导老师:
2.运行界面截图如下:
六、小结
1、在创建邻接多重表时,由于邻接多重表的数据类型为字符型,键盘输入总是很难控制。
这时可以通过人为设置函数过滤去键盘输入中的空格。
2、在邻接多重表上,各种基本操作的实现和邻接表相似。
3、在邻接多重表中,所有依附于同一顶点的边串联在同一链表中。
数据结构实验报告图实验
图实验一,邻接矩阵的实现1.实验目的(1)掌握图的逻辑结构(2)掌握图的邻接矩阵的存储结构(3)验证图的邻接矩阵存储及其遍历操作的实现2.实验内容(1)建立无向图的邻接矩阵存储(2)进行深度优先遍历(3)进行广度优先遍历3.设计与编码#ifndef MGraph_H#define MGraph_Hconst int MaxSize = 10;template<class DataType>class MGraph{public:MGraph(DataType a[], int n, int e);~MGraph(){}void DFSTraverse(int v);void BFSTraverse(int v);private:DataType vertex[MaxSize];int arc[MaxSize][MaxSize];int vertexNum, arcNum;};#endif#include<iostream>using namespace std;#include ""extern int visited[MaxSize];template<class DataType>MGraph<DataType>::MGraph(DataType a[], int n, int e){int i, j, k;vertexNum = n, arcNum = e;for(i = 0; i < vertexNum; i++)vertex[i] = a[i];for(i = 0;i < vertexNum; i++)for(j = 0; j < vertexNum; j++)arc[i][j] = 0;for(k = 0; k < arcNum; k++){cout << "Please enter two vertexs number of edge: ";cin >> i >> j;arc[i][j] = 1;arc[j][i] = 1;}}template<class DataType>void MGraph<DataType>::DFSTraverse(int v){cout << vertex[v];visited[v] = 1;for(int j = 0; j < vertexNum; j++)if(arc[v][j] == 1 && visited[j] == 0)DFSTraverse(j);}template<class DataType>void MGraph<DataType>::BFSTraverse(int v){int Q[MaxSize];int front = -1, rear = -1;cout << vertex[v];visited[v] = 1;Q[++rear] = v;while(front != rear){v = Q[++front];for(int j = 0;j < vertexNum; j++)if(arc[v][j] == 1 && visited[j] == 0){cout << vertex[j];visited[j] = 1;Q[++rear] = j;}}}#include<iostream>using namespace std;#include ""extern int visited[MaxSize];template<class DataType>MGraph<DataType>::MGraph(DataType a[], int n, int e){int i, j, k;vertexNum = n, arcNum = e;for(i = 0; i < vertexNum; i++)vertex[i] = a[i];for(i = 0;i < vertexNum; i++)for(j = 0; j < vertexNum; j++)arc[i][j] = 0;for(k = 0; k < arcNum; k++){cout << "Please enter two vertexs number of edge: ";cin >> i >> j;arc[i][j] = 1;arc[j][i] = 1;}}template<class DataType>void MGraph<DataType>::DFSTraverse(int v){cout << vertex[v];visited[v] = 1;for(int j = 0; j < vertexNum; j++)if(arc[v][j] == 1 && visited[j] == 0)DFSTraverse(j);}template<class DataType>void MGraph<DataType>::BFSTraverse(int v){int Q[MaxSize];int front = -1, rear = -1;cout << vertex[v];visited[v] = 1;Q[++rear] = v;while(front != rear){v = Q[++front];for(int j = 0;j < vertexNum; j++)if(arc[v][j] == 1 && visited[j] == 0){cout << vertex[j];visited[j] = 1;Q[++rear] = j;}}}4.运行与测试5.总结与心得通过该实验的代码编写与调试,熟悉了邻接矩阵在图结构中的应用,在调试过程中遇到很多的问题,在解决问题过程中也使我的写代码能力得到提升二,邻接表的实现1.实验目的(1)掌握图的逻辑结构(2)掌握图的邻接表存储结构(3)验证图的邻接表存储及其遍历操作的实现2.实验内容(1)建立一个有向图的邻接表存储结构(2)对建立的有向图进行深度优先遍历(3)对建立的有向图进行广度优先遍历3.设计与编码#ifndef ALGraph_H#define ALGraph_Hconst int MaxSize = 10;struct ArcNode{int adjvex;ArcNode * next;};template<class DataType>struct VertexNode{DataType vertex;ArcNode * firstedge;};template<class DataType>class ALGraph{public:ALGraph(DataType a[], int n, int e);~ALGraph();void DFSTraverse(int v);void BFSTraverse(int v);private:VertexNode<DataType> adjlist[MaxSize];int vertexNum, arcNum;};#endif#include<iostream>using namespace std;#include""extern int visited[MaxSize];template<class DataType>ALGraph<DataType>::ALGraph(DataType a[], int n, int e) {ArcNode * s;int i, j, k;vertexNum = n; arcNum = e;for(i = 0; i < vertexNum; i++){adjlist[i].vertex = a[i];adjlist[i].firstedge = NULL;}for(k = 0; k < arcNum; k++){cout << "Please enter the edge of the serial number of two vertices: ";cin >> i >> j;s = new ArcNode; s->adjvex = j;s->next = adjlist[i].firstedge;adjlist[i].firstedge = s;}}template<class DataType>ALGraph<DataType>::~ALGraph(){ArcNode * p = NULL;for(int i = 0; i < vertexNum; i++){p = adjlist[i].firstedge;while(p != NULL){adjlist[i].firstedge = p->next;delete p;p = adjlist[i].firstedge;}}}template<class DataType>void ALGraph<DataType>::DFSTraverse(int v){ArcNode * p = NULL; int j;cout << adjlist[v].vertex;visited[v] = 1;p = adjlist[v].firstedge;while(p != NULL){j = p->adjvex;if(visited[j] == 0) DFSTraverse(j);p = p->next;}}template<class DataType>void ALGraph<DataType>::BFSTraverse(int v){int Q[MaxSize];int front = -1, rear = -1;ArcNode * p = NULL;cout << adjlist[v].vertex; visited[v] = 1; Q[++rear] = v;while(front != rear){v = Q[++front];p = adjlist[v].firstedge;while(p != NULL){int j = p->adjvex;if(visited[j] == 0){cout << adjlist[j].vertex; visited[j] = 1; Q[++rear] = j;}p = p->next;}}}#include<iostream>using namespace std;#include""int visited[MaxSize] = {0};int main(){char ch[] = {'A','B','C','D','E'};int i;ALGraph<char> ALG(ch, 5, 6);for(i = 0; i < MaxSize; i++)visited[i] = 0;cout << "Depth-first traverse sequence is: ";(0);cout << endl;for(i = 0; i < MaxSize; i++)visited[i] = 0;cout << "Breadth-first traverse sequence is: ";(0);cout << endl;return 0;}4.运行与调试5.总结与心得通过该实验,掌握了图的邻接表存储结构。
图的邻接矩阵存储(数组表示)、简单输出实验五(数据结构)
《数据结构》实验报告五实验内容:图的邻接矩阵存储(数组表示)、简单输出学号:姓名:郑郑一、上机实验的问题和要求:阅读理解上面第一个关于图的邻接矩阵的程序,做下列题目。
(1)根据教科书P157页的G2图(无向图),输入数据运行程序。
(2)再适当修改上述程序,使它适用于G1图(有向图),输入数据运行程序。
二、程序设计的基本思想,原理和算法描述:无向图的邻接矩阵是对称的,而有向图的邻接矩阵是非对称的。
只需把无向图中G[i][j]=1;G[j][i]=1;改为g[i][j]=1;即可。
三、调试和运行程序过程中产生的问题及采取的措施:调试程序时未发现错误,得到了期望的结果。
四、源程序及注释程序名:28.cpp# include <stdio.h># include <stdlib.h># define MAX 20typedef int VexType;typedef VexType Mgraph[MAX][MAX]; /* Mgraph是二维数组类型标识符*//* 函数原形声明*/void creat_mg(Mgraph G);void out_mg(Mgraph G);Mgraph G1; /* G1是邻接矩阵的二维数组名*/ int n,e,v0;/* 主函数*//* main *//* 建立邻接矩阵*/void creat_mg(Mgraph G){ int i,j,k;printf("\n n,e=?");scanf("%d%d", &n,&e); /* 输入顶点数n,边数e */for(i=1; i<=n;i++)for(j=1;j<=n;j++) G[i][j]=0;/* 如果是网,G[i][j]=0该为G[i][j]=32767(无穷)*/ for(k=1;k<=e;k++) /* 组织边数的循环*/ { printf("\n vi,vj=?");scanf("%d%d", &i,&j); /* 输入一条边的两个顶点编号i,j */G[i][j]=1; G[j][i]=1; /* 无向图的邻接矩阵是对称矩阵*//* 如果是网,还要输入边的权值w,再让G[i][j]=w */}} /* creat_mg *//* 邻接矩阵简单输出,为了检查输入是否正确*/void out_mg(Mgraph G){ int i,j;char ch;for(i=1; i<=n;i++) /* 矩阵原样输出*/{ printf("\n ");for(j=1;j<=n;j++) printf("%5d",G[i][j]);}/* 输出所存在的边*/for(i=1; i<=n;i++)for(j=1;j<=n;j++)if(G[i][j]==1)printf("\n 存在边< %d,%d >",i,j);printf("\n\n 打回车键,继续。
数据结构实验四:图的应用
数据结构实验报告20 10 ~20 11 学年第一学期2008级计算机专业班级:学号:姓名:实验四图的应用一、实验目的:1.掌握图的存储结构及其构造方法2.掌握图的两种遍历算法及其执行过程二、实验内容:以邻接矩阵或邻接表为存储结构,以用户指定的顶点为起始点,实现无向连通图的深度优先及广度优先搜索遍历,并输出遍历的结点序列。
提示:首先,根据用户输入的顶点总数和边数,构造无向图,然后以用户输入的顶点为起始点,进行深度优先和广度优先遍历,并输出遍历的结果。
三、实验要求:1.各班学号为单号的同学采用邻接矩阵实现,学号为双号的同学采用邻接表实现。
2.C/ C++完成算法设计和程序设计并上机调试通过。
3.撰写实验报告,提供实验结果和数据。
4.写出算法设计小结和心得。
四、程序源代码:#include<iostream.h>typedef char vextype;const MAXVER=21;typedef struct listnode {int adjvex;listnode* next;}listnode;//表结点typedef struct{vextype data;listnode *first;}headnode;//头结点typedef struct{headnode vexs[MAXVER];int vexnum,arcnum;} ALgraph;//图void createALgraph(ALgraph &G){int i, s, d;listnode *p,*q;cout<<"输入图的顶点数和边数:"; cin>>G.vexnum>>G.arcnum;for(i=1;i<=G.vexnum;i++){cout<<"\n输入第"<<i<<"个顶点信息:"; cin>>G.vexs[i].data;G.vexs[i].first=NULL;} //输入第i个结点值并初始化第i个单链表为空for(i=1; i<=G.arcnum; i++){cout<<"\n输入第"<<i<<"条边的始点和终点:";cin>>s>>d;//s为始点,d为终点p=new listnode;p->adjvex=d;p->next=G.vexs[s].first;G.vexs[s].first=p;//将新建的以d为信息的表结点p插入s 单链表的头结点后q=new listnode;q->adjvex=s;q->next=G.vexs[d].first;G.vexs[d].first=q;//将新建的以s为信息的表结点q插入d 单链表的头结点后}}int visited[MAXVER];//定义全局数组遍历visitedvoid dfs(ALgraph G, int v)//被遍历的图G采用邻接表作为存储结构,v为出发顶点编号{listnode *p;cout<<G.vexs[v].data;visited[v]=1;p=G.vexs[v].first;while(p!=NULL){if(visited[p->adjvex]==0)dfs(G,p->adjvex);//若p所指表结点对应的邻接顶点未访问则递归地从该顶点出发调用dfsp=p->next;}}void dfsTraverse(ALgraph G){int v;//遍历图之前初始化各未访问的顶点for(v=1; v<=G.vexnum; v++)visited[v]=0;//从各个未被访问过的顶点开始进行深度遍历for(v=1;v<=G.vexnum;v++)if(visited[v]==0) dfs(G,v);}void BFS(ALgraph G, int v)//从顶点编号v出发,广度遍历邻接表存储的图G{int queue[MAXVER], front ,rear;listnode* p;front=rear=0;cout<<G.vexs[v].data;visited[v]=1;queue[++rear]=v;while(front!=rear){v=queue[++front];p=G.vexs[v].first;while(p!=NULL){if(visited[p->adjvex]==0){v=p->adjvex;cout<<G.vexs[v].data;visited[v]=1;queue[++rear]=v;}p=p->next;}} }void BFSTraverse(ALgraph G){int v;//遍历G以前,初始化visited数组为0 for(v=1;v<=G.vexnum;v++)visited[v]=0;for(v=1;v<=G.vexnum;v++)if(visited[v]==0)BFS(G,v);}void main(){ALgraph g;createALgraph(g);cout<<endl<<"深度遍历结果为:";dfsTraverse(g);cout<<endl<<"广度遍历结果为:";BFSTraverse(g);cout<<endl;}五、程序运行情况(写出输入数据及运行结果)六、小结(包括收获、心得体会、存在的问题及解决问题的方法、建议等)本次实验是对邻接表和邻接矩阵的应用,使用邻接表为存储结构实现无向连通图的深度优先和广度优先搜索遍历,通过本次实验,我对图的存储结构及其构造方法有了进一步了解,对深度遍历和广度遍历的实现有了更深的认识。
数据结构图实验报告
数据结构教程上机实验报告实验七、图算法上机实现一、实验目的:1.了解熟知图的定义和图的基本术语,掌握图的几种存储结构。
2.掌握邻接矩阵和邻接表定义及特点,并通过实例解析掌握邻接矩阵和邻接表的类型定义。
3.掌握图的遍历的定义、复杂性分析及应用,并掌握图的遍历方法及其基本思想。
二、实验内容:1.建立无向图的邻接矩阵2.图的深度优先搜索3.图的广度优先搜索三、实验步骤及结果:1.建立无向图的邻接矩阵:1)源代码:#include "stdio.h"#include "stdlib.h"#define MAXSIZE 30typedef structchar vertex[MAXSIZE];//顶点为字符型且顶点表的长度小于MAXSIZEint edges[MAXSIZE][MAXSIZE];//边为整形且edges为邻近矩阵}MGraph;//MGraph为采用邻近矩阵存储的图类型void CreatMGraph(MGraph *g,int e,int n){//建立无向图的邻近矩阵g->egdes,n为顶点个数,e为边数int i,j,k;printf("Input data of vertexs(0~n-1):\n");for(i=0;i<n;i++)g->vertex[i]=i; //读入顶点信息for(i=0;i<n;i++)for(j=0;j<n;j++)g->edges[i][j]=0; //初始化邻接矩阵for(k=1;k<=e;k++)//输入e条边{printf("Input edges of(i,j):");scanf("%d,%d",&i,&j);g->edges[i][j]=1;g->edges[j][i]=1;}void main(){int i,j,n,e;MGraph *g; //建立指向采用邻接矩阵存储图类型指针g=(MGraph*)malloc(sizeof(MGraph));//生成采用邻接举证存储图类型的存储空间printf("Input size of MGraph:"); //输入邻接矩阵的大小scanf("%d",&n);printf("Input number of edge:"); //输入邻接矩阵的边数scanf("%d",&e);CreatMGraph(g,e,n); //生成存储图的邻接矩阵printf("Output MGraph:\n");//输出存储图的邻接矩阵for(i=0;i<n;i++){for(j=0;j<n;j++)printf("%4d",g->edges[i][j]);printf("\n");}}2)运行结果:2.图的深度优先搜索:1)源代码:#include "stdio.h"#include "stdlib.h"#define MAXSIZE 30typedef struct node//邻接表结点{int adjvex;//邻接点域struct node *next;//指向下一个邻接边结点的指针域}EdgeNode; //邻接表结点类型typedef struct vnode//顶点表结点{int vertex;//顶点域EdgeNode *firstedge; //指向邻接表第一个邻接边节点的指针域}VertexNode;//顶点表结点类型void CreatAdjlist(VertexNode g[],int e,int n){//建立无向图的邻接表,n为顶点数,e为边数,g[]存储n个顶点表结点EdgeNode *p;int i,j,k;printf("Input data of vetex(0~n-1);\n");for(i=0;i<n;i++)//建立有n个顶点的顶点表{g[i].vertex=i; //读入顶点i信息g[i].firstedge=NULL; //初始化指向顶点i的邻接表表头指针}for (k=1;k<=e;k++)//输入e条边{printf("Input edge of(i,j):");scanf("%d,%d",&i,&j);p=(EdgeNode*)malloc(sizeof(EdgeNode));p->adjvex=j; //在顶点vi的邻接表中添加邻接点为j的结点p->next=g[i].firstedge; //插入是在邻接表表头进行的g[i].firstedge=p;p=(EdgeNode*)malloc(sizeof(EdgeNode));p->adjvex=i; //在顶点vj的邻接表中添加邻接点为i的结点p->next=g[j].firstedge; //插入是在邻接表表头进行的g[j].firstedge=p;}}int visited[MAXSIZE]; //MAXSIZE为大于或等于无向图顶点个数的常量void DFS(VertexNode g[],int i){EdgeNode *p;printf("%4d",g[i].vertex); //输出顶点i信息,即访问顶点ivisited[i]=1;p=g[i].firstedge; //根据顶点i的指针firstedge查找其邻接表的第一个邻接边结点while(p!=NULL){if(!visited[p->adjvex]) //如果邻接的这个边结点未被访问过DFS(g,p->adjvex); //对这个边结点进行深度优先搜索p=p->next; //查找顶点i的下一个邻接边结点}}void DFSTraverse(VertexNode g[],int n){//深度优先搜索遍历以邻接表存储的图,其中g为顶点数,n为顶点个数int i;for(i=0;i<n;i++)visited[i]=0; //访问标志置0for(i=0;i<n;i++)//对n个顶点的图查找未访问过的顶点并由该顶点开始遍历if(!visited[i]) //当visited[i]等于0时即顶点i未访问过DFS(g,i); //从未访问过的顶点i开始遍历}void main(){int e,n;VertexNode g[MAXSIZE]; //定义顶点表结点类型数组gprintf("Input number of node:\n");//输入图中节点个数边的个数scanf("%d",&n);printf("Input number of edge:\n");//输入图中边的个数scanf("%d",&e);printf("Make adjlist:\n");CreatAdjlist(g,e,n); //建立无向图的邻接表printf("DFSTraverse:\n");DFSTraverse(g,n); //深度优先遍历以邻接表存储的无向图printf("\n");}2)运行结果:3.图的广度优先搜索:1)源代码:#include "stdio.h"#include "stdlib.h"#define MAXSIZE 30typedef struct node1//邻接表结点{int adjvex; //邻接点域struct node1 *next;//指向下一个邻接边结点的指针域}EdgeNode; //邻接表结点类型typedef struct vnode//顶点表结点{int vertex;//顶点域EdgeNode *firstedge; //指向邻接表第一个邻接边结点的指针域}VertexNode; //顶点表结点类型void CreatAdjlist(VertexNode g[],int e,int n){ //建立无向图的邻接表,n为顶点数,e为边数,g[]存储n个顶点表结点EdgeNode *p;int i,j,k;printf("Input data of vetex(0~n-1):\n");for(i=0;i<n;i++) //建立有n个顶点的顶点表{g[i].vertex=i; //读入顶点i信息g[i].firstedge=NULL; //初始化指向顶点i的邻接表表头指针}for(k=1;k<=e;k++) //输入e条边{printf("Input edge of(i,j):");scanf("%d,%d",&i,&j);p=(EdgeNode *)malloc(sizeof(EdgeNode));p->adjvex=j;//在定点vi的邻接表中添加邻接点为j的结点p->next=g[i].firstedge;//插入是在邻接表表头进行的g[i].firstedge=p;p=(EdgeNode *)malloc(sizeof(EdgeNode));p->adjvex=i; //在顶点vj的邻接表中添加邻接点为i的结点p->next=g[j].firstedge; //插入是在邻接表表头进行的g[j].firstedge=p;}}typedef struct node{int data;struct node *next;}QNode; //链队列结点的类型typedef struct{QNode *front,*rear; //将头、尾指针纳入到一个结构体的链队列}LQueue; //链队列类型void Init_LQueue(LQueue **q) //创建一个带头结点的空队列{QNode *p;*q=(LQueue *)malloc(sizeof(LQueue)); //申请带头、尾指针的链队列p=(QNode *)malloc(sizeof(QNode)); //申请链队列的头结点p->next=NULL;//头结点的next指针置为空(*q)->front=p; //队头指针指向头结点(*q)->rear=p; //队尾指针指向头结点}int Empty_LQueue(LQueue *q) //判队空{if(q->front==q->rear) //队为空return 1;elsereturn 0;}void In_LQueue(LQueue *q,int x) //入队{QNode *p;p=(QNode *)malloc(sizeof(QNode)); //申请新链队列结点p->data=x;p->next=NULL; //新结点作为队尾结点时其next 域为空q->rear->next=p; //将新结点*p链到原队尾结点之后q->rear=p; //使队尾指针指向新的队尾结点*p}void Out_LQueue(LQueue *q,int *x) //出队{QNode *p;if(Empty_LQueue(q))printf("Queue is empty!\n");//对空,出队失败else{p=q->front->next; //指针p指向链队列第一个数据结点(即对头结点)q->front->next=p->next;//头结点的next指针指向链队列第二个数据结点(即删除第一个数据结点)*x=p->data; //将删除的对头结点数据经由x返回free(p);if(q->front->next==NULL) //出队后队为空,则置为空队列q->rear=q->front;}}int visited[MAXSIZE]; //MAXSIZE为大于或等于无向图顶点个数的常量void BFS(VertexNode g[],LQueue *Q,int i){//广度优先搜索遍历邻接表存储的图,g为顶点表,Q为队指针,i为第i个顶点int j,*x=&j;EdgeNode *p;printf("%4d",g[i].vertex); //输出顶点i信息,即访问顶点ivisited[i]=1; //置顶点i为访问过标志In_LQueue(Q,i); //顶点i入队Qwhile(!Empty_LQueue(Q)) //当队Q非空时{Out_LQueue(Q,x); //对头顶点出队并送j(暂记为顶点j)p=g[j].firstedge;//根据顶点j的表头指针查找其邻接表的第一个邻接边结点while(p!=NULL){if(!visited[p->adjvex])//如果邻接的这个边结点未被访问过{printf("%4d",g[p->adjvex].vertex); //输出这个邻接边结点的顶点信息visited[p->adjvex]=1; //置该邻接边结点为访问过标志In_LQueue(Q,p->adjvex); //将该邻接边结点送人队Q}p=p->next;//在顶点j的邻接表中查找j的下一个邻接边结点}}}void main(){int e,n;VertexNode g[MAXSIZE];//定义顶点表结点类型数组g LQueue *q;printf("Input number of node:\n"); //输入图中结点个数scanf("%d",&n);printf("Input number of edge:\n");//输入图中边的个数scanf("%d",&e);printf("Make adjlist:\n ");CreatAdjlist(g,e,n);//建立无向图的邻接表Init_LQueue(&q);//队列q初始化printf("BFSTraverse:\n");BFS(g,q,0); //广度优先遍历以邻接表存储的无向图printf("\n");}2)运行结果:三、实验总结:1.通过本次试验让我对图的遍历以及图的深度和广度优先搜索有了更深刻的记忆和理解,将课本理论的知识得以实践。
数据结构实验报告—图
《算法与数据结构》课程实验报告一、实验目的1.实现图的存储结构;2.通过图的相关算法实现,掌握其算法思想。
二、实验内容及要求1.无向带权图的存储结构(邻接矩阵、邻接表等自选)2.实现图的相关算法(1)计算指定顶点的度(2)图的深度优先遍历和广度优先遍历算法(3)分别使用Kruskal和Prim算法求解该图的最小生成树三、系统分析(1)数据方面:定义图的模板基类,在模板类定义中的数据类型参数表<class T,class E>中,T是定点数据的类型,E是边上所附数据的类型。
这个模板基类是按照带权无向图来定义的。
在该实验中定点的数据的类型为char型,边上所附数据的类型为int型。
且图的创建为无向图。
(2)功能方面:1.能够实现图的创建以及图的输出。
2.能够返回顶点在图中位置以及图中位置对应顶点的值。
3.返回当前图中的边数与顶点数。
4.返回输入边的权值。
5.能够插入一个顶点或插入顶点与之相关联的边。
6.删除边或删除顶点与之相关联的边。
7.计算顶点的度。
8.实现深度优先搜索、广度优先搜索遍历。
9.Kruskal算法、Prim算法生成最小生成树。
四、系统设计(1)设计的主要思路根据实验要求,首先确定图的存储结构,在根据存储结构编写模板类,并将需要实现的功能代码完善,再写出实现各个功能的菜单并进行调试。
由于在编写由图生成最小生成树中采用了最小堆以及并查集的算法,故需要将这两个个类的代码完成并进行调试。
最后将此次实验所涉及的类全部整理完全后,通过之前编写的菜单对功能进行依次调试,完成此次实验。
(2)数据结构的设计图是非线性结构,它的每一个顶点可以与多个其他顶点相关联,各顶点之间的关系是任意的。
可以用很多方法来存储图结构。
在此采用邻接矩阵来存储图结构。
首先将所有顶点的信息组织成一个顶点表,然后利用一个矩阵来表示各顶点之间的邻接关系,称为邻接矩阵。
下面针对带权无向图的邻接矩阵作出说明。
其中有一个类型为顺序表的顶点表向量VerticesList,用以存储顶点的信息,还有一个作为邻接矩阵使用的二维数组Edge,用以存储图中的边,其矩阵元素个数取决于顶点个数,与边数无关。
数据结构实验报告无向图邻接矩阵存储结构
6. 选择判断是否连通 7. 选择求最小生成树
8. 选择求各顶点的度 9. 选择退出,重新运行,此次建立 A2的图,再次进行测试。
2 概要设计
2.1 ADT 描述
ADT Glist
{
{VR}={ 图的顶点和边 }
VR={<v,w> | v,w ∈V, <v,w> 表示顶点 v 和 w 间的边; }
基本操作:
此次课程设计根据课堂讲授内容,下发任务书,要求学生完成相应系统,以消化课堂所讲
解的内容;通过调试典型例题或习题积累调试 C++程序从而获得数据结构的编程经验;通过完
成此项课程设计,逐渐培养学生的编程能力、用计算机解决实际问题的能力,并充分理解图的
矩阵储存方法。
此次课程设计题目为《无向图的邻接矩阵存储结构》,所利用工具为
初始化空图;
输入建立图;
深度优先遍历图; 确定图中的顶点数目;
确定图中边的数目; 在图中插入一个顶点;
在图中插入一条边; 删除图中一个顶点
删除图中的一条边;
求顶点的度; 求最小生成树; } ADT Graph 。
2.2 程序模块结构
个人资料整理 仅限学习使用
主函数 main 创建函数 菜单
边的插入函数
[5] 胡学钢 . 数据结构 (C 语言版 > . 高等教育出版社 .2004 年 8 月
指导教师签名日期年月日
系 主 任审核日期年月日 目录
个人资料整理 仅限学习使用
摘要
随着计算机的普及,涉及计算机相关的科目也越来越普遍,其中数据结构是计算机 专业重要的专业基础课程与核心课程之一,为适应我国计算机科学技术的发展和应用, 学好数据结构非常必要,然而要掌握数据结构的知识非常难,所以对“数据结构”的课 程设计比不可少。本说明书是对“无向图的邻接矩阵存储结构”课程设计的说明。
国家开放大学《数据结构》课程实验报告(实验5——图的存储方式和应用)参考答案
scanf("%d%d",&i,&j);
GA[i][j]=GA[j][i]=1;
}
}
else if(k1==0 && k2!=0) /*建立无向有权图*/
{
printf("输入%d条无向有权边的起点和终点序号及权值!\n",e);
for(k=1; k<=e; k++)
{
scanf("%d%d%d",&i,&j,&w);
printf("输入待处理图的顶点数和边数:");
scanf("%d%d",&n,&e);
/*输入有无向选择和有无权选择*/
printf("输入有无向选择和有无权选择(0为无,非0为有):");
scanf("%d%d",&k1,&k2);
CreateMatrix(gv,ga,n,e,k1,k2); /*建立图的邻接矩阵*/
printf("%6s","∞");
else
printf("%6d",GA[i][j]);
}
printf("\n");
}
}
实验结果:
测试用例1无向无权图如下图所示。
程序运行结果如下:
测试用例2有向有权图如下图所示。
程序运行结果如下:
实
验
小
结
(1)具有n个顶点的图,其邻接矩阵为n×n阶方阵,用二维数组存储,行列下标为0~n-1。
{
int i,j;
printf("顶点");
数据结构实验报告
数据结构实验报告(实验五&&实验六)班级:软件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.结果和分析:图的点数序列从零开始。
无向图深度遍历邻接矩阵报告
55.G->arcs[i][j].adj=1;
56.G->arcs[j][i].adj=1;
57.}
58.return(OK);
59.}
60.
61.
62.void DepthFirstSearch(AdjMatrix G,int v)
63.{int j;
输出邻接矩阵0 1
1 0
实际结果:
第二组测试:
输入数据:顶点:0,1,2,3,4
预测结果:输出结点数据:0,1,2,3,4
输出邻接矩阵01 1 1 0
1 0 0 1 0
1 0 0 1 1
1 1 1 0 1
0 0 1 1 0
实际结果:
第三组测试:
输入数据:顶点:0,1,2,3,4 5 6
预测结果:输出结点数据:0123456
70.}
71.void TraverseGraph(AdjMatrix G)
72.{int i;
73.for(i=0;i<G.vexnum;i++) visited[i]=FALSE;
74.for(i=0;i<G.vexnum;i++)
75.if(!visited[i]) DepthFirstSearch(G,i);
typedef struct
{
VertexData vertex[MAX_VERTEX_NUM];//为顶点的集合
ArcNode arcs[MAX_VERTEX_NUM][MAX_VERTEX_NUM];
int vexnum,arcnum;//vexnum为顶点数,arcnum为弧数
数据结构 第六次实验报告
实验六无向图K1373-4-19 刘洋 20139730419一、实验任务和要求1.掌握无向图的邻接矩阵和邻接表的构造与应用。
2.实现无向图的邻接矩阵和无向图的邻接表的存储结构的基本操作。
二、原理分析和程序设计无向图的邻接矩阵菜单界面:无向图的邻接矩阵读入文件界面:无向图的邻接矩阵的深度优先遍历源码:void depthfirstsearch(int startpoint,int visited[],void visit(char item))//深度优先遍历{int neighborpoint;visit(getvalue(startpoint));visited[startpoint]=1;neighborpoint=getfirstneighbor(startpoint);while(neighborpoint!=-1)if(!visited[neighborpoint])depthfirstsearch(neighborpoint,visited,visit);neighborpoint=getnextneighbor(startpoint,neighborp oint);}}无向图的邻接矩阵的深度优先遍历运行界面:无向图的邻接矩阵的广度优先遍历源码:void breadthfirstsearch( int startpoint,int visited[],void visit(char item))//广度优先遍历{char getqueuehead,neighborpoint;visit(getvalue(startpoint));visited[startpoint]=1;enqueue(startpoint);while(!isempty()){getqueuehead=dequeue();neighborpoint=getfirstneighbor(getqueuehead);while(neighborpoint!=-1){if(!visited[neighborpoint]){visit(getvalue(neighborpoint));visited[neighborpoint]=1;enqueue(neighborpoint);}neighborpoint=getnextneighbor(getqueuehead,neighbo rpoint);}}}无向图的邻接矩阵的广度优先遍历运行界面:无向图的邻接表实验菜单界面:无向图的邻接表读入文件界面:无向图的邻接表的深度优先遍历源码:void DFSTraverse()//深度优先遍历入口{int i;int *flag=(int*)malloc(sizeof(int)*graphnow.nodelength);//访问标志数组,0表示未被访问,1表示已访问for(i=0;i<graphnow.nodelength;i++) //标志位数组初始化,全部赋值为0flag[i]=0;int *stackarray=(int*)malloc(sizeof(int)*(graphnow.nodelength));//保存路径的数组,起到栈的作用for(i=0;i<graphnow.nodelength;i++)//栈的初始状态全部赋值为-1{stackarray[i]=-1;}for(i=0;i<graphnow.nodelength;i++) //每一个结点都作为起始结点一次,确保非联通图也可以完成遍历if(flag[i]==0)TDFSTraverse(i,flag,stackarray);}void TDFSTraverse(int row,int flag[], int stackarray[])//深度优先遍历函数{int *adjvexarray; //邻接边信息链表转换成的数组int nextnum; //下一个邻接点的编号int visitednum=1; //已访问结点的个数stackarray[0]=1; //0号坐标中存放访问过的结点数量,此处预设为1,最后访问结点数量需要减一while(row!=-1&&stackarray[0]<graphnow.nodelength) {if(flag[row]==0){printf("%c ",getheaddata(row));flag[row]=1;stackarray[stackarray[0]]=row;stackarray[0]++;}adjvexarray=nodetoarraydata(row);nextnum=1;getnextnode(nextnum,row);while(flag[row]==1&&row!=-1&&stackarray[0]<graphno w.nodelength){if(nextnum>=adjvexarray[0])row=-1;elserow=adjvexarray[nextnum];nextnum++;}TDFSTraverse(row,flag,stackarray);visitednum=stackarray[0]-1;if(stackarray[0]<graphnow.nodelength&&row==-1){visitednum--;if(visitednum<0) row=-1;else row=stackarray[visitednum];}}}无向图的邻接表的深度优先遍历运行界面:无向图的邻接表的广度优先遍历源码:void BFSTraverse()//广度优先遍历入口{int *flag=(int*)malloc(graphnow.nodelength*sizeof(int));//访问标志数组,0表示未被访问,1表示已访问for(int i=0;i<graphnow.nodelength;i++) //标志位数组初始化,全部赋值为0flag[i]=0;for(i=0;i<graphnow.nodelength;i++) //每一个结点都作为起始结点一次,确保非联通图也可以完成遍历if(flag[i]==0)TBFSTraverse(i,flag);}void TBFSTraverse(int row,int flag[])//广度优先遍历递归函数{int *adjvexdataarray,i;if(flag[row]==0){printf("%c ",getheaddata(row));flag[row]=1;}adjvexdataarray=nodetoarraydata(row);for(i=1;i<adjvexdataarray[0];i++){if(flag[adjvexdataarray[i]]==0){printf("%c ",getheaddata(adjvexdataarray[i]));flag[adjvexdataarray[i]]=1;enqueue(adjvexdataarray[i]);}}if((row=dequeue())!=-1){TBFSTraverse(row,flag);}}无向图的邻接表的广度优先遍历,运行图:三、实验小结本次实验进行了图以及它的储存实现,熟悉了图的遍历操作的程序实现,但在这次试验中还是遇见了许多麻烦比如:不知道怎么建立无向图,深度优先遍历图和广度优先遍历图的区别和关系,不过通过本次试验让我了解到了什么是图的构造还有应用,同时在同学的帮助下还让我了解到了什么叫深度优先遍历图和广度优先遍历图,同时让我明白遍历的重要性。
数据结构实验报告图的存储
数据结构实验报告图的存储数据结构图实验报告一、实验目的和要求(1)掌握图的相关概念,包括图,有向图,无向图,完全图,子图,连通图,度,入度,出度,简单回路和环等定义。
(2)重点掌握图的各种存储结构,包括邻接矩阵和邻接表等。
(3)重点掌握图的基本运算,包括创建图,输出图,深度优先遍历,广度优先遍历等。
(4)掌握图的其他运算,包括最小生成树,最短路径,拓扑排序和关键路径等算法。
(5)灵活运用图这种数据结构解决一些综合应用问题。
二、实验内容和方法(1)实验内容:1、编写一个程序algo8-1.cpp,实现不带权图和带权图的邻接矩阵与邻接表的相互转换算法、输出邻接矩阵与邻接表的算法,并在此基础上设计一个程序exp8-1.cpp实现如下功能:①建立如图1所示的有向图G的邻接矩阵,并输出;②由有向图G的邻接矩阵产生邻接表,并输出;③再由②的邻接表产生对应的邻接矩阵,并输出。
图12、编写一个程序algo8-2.cpp,实现图的遍历运算,并在此基础上设计一个程序exp8-2.cpp完成如下功能:①输出图1所示的有向图G从顶点0开始的深度优先遍历序列(递归算法);②输出图1所示的有向图G从顶点0开始的深度优先遍历序列(非递归算法);③输出图1所示的有向图G从顶点0开始的广度优先遍历序列。
3、设计一个程序exp8-3.cpp,采用邻接表存储图,并输出图8.1(a)中从指定顶点1出发的所有深度优先遍历序列。
(2)实验方法:1、综合运用课本所学的知识,用不同的算法实现在不同的程序功能。
2、结合指导老师的指导,解决程序中的问题,正确解决实际中存在的异常情况,逐步改善功能。
3、根据实验内容,编译程序。
三、实验环境:Windows 7,Visual C++6.0三、实验过程描述文件graph.h中定义了图的邻接矩阵表示类型和邻接表表示类型,该头文件在以下三个实验中都会使用到。
其代码如下:#ifndef GRAPH_H_INCLUDED#define GRAPH_H_INCLUDEDtypedef int InfoType;#define MAXV 100 //最大顶点个数#define INF 32767 //INF表示无限大//以下定义邻接矩阵类型typedef struct{int no;InfoType info;}VertexType;typedef struct{int edges[MAXV][MAXV];int n,e;VertexType vexs[MAXV];}MGraph;//以下定义邻接表类型typedef struct ANode{int adjvex;struct ANode* nextarc;InfoType info;}ArcNode;typedef int Vertex;typedef struct VNode{Vertex data;实验①源程序。
数据结构 图实验报告
数据结构图实验报告数据结构图实验报告引言:数据结构是计算机科学中非常重要的一个概念,它用于存储和组织数据,使得数据的操作更加高效和方便。
图是一种常见的数据结构,它由节点和边组成,用于表示各种实际问题中的关系和连接。
本实验旨在通过实际操作,深入理解图的基本概念和常见操作。
实验目的:1. 理解图的基本概念和特性;2. 掌握图的存储结构和基本操作;3. 实现图的遍历算法;4. 分析图的应用场景。
实验过程:1. 图的存储结构:在本次实验中,我们选择邻接矩阵来存储图。
邻接矩阵是一个二维数组,其中行和列分别表示图中的节点,数组元素表示节点之间的边的关系。
具体而言,如果节点i和节点j之间存在边,则邻接矩阵中的第i行第j列元素为1;否则为0。
2. 图的基本操作:在实验中,我们实现了以下几个图的基本操作:- 添加节点:通过向邻接矩阵中添加一行一列,并设置对应的边的关系,来添加一个节点;- 添加边:通过修改邻接矩阵中对应元素的值,来添加一条边;- 删除节点:通过删除邻接矩阵中对应行和列,并更新其他节点的索引,来删除一个节点;- 删除边:通过修改邻接矩阵中对应元素的值,来删除一条边;- 查找节点:通过遍历邻接矩阵,找到对应节点的索引;- 查找边:通过遍历邻接矩阵,找到对应边的关系。
3. 图的遍历算法:在实验中,我们实现了深度优先搜索(DFS)和广度优先搜索(BFS)两种图的遍历算法。
DFS通过递归的方式,先访问当前节点,再依次访问相邻节点,直到所有节点都被访问。
BFS则通过队列的方式,先访问当前节点,再依次访问当前节点的相邻节点,直到所有节点都被访问。
实验结果:通过实验,我们成功实现了图的存储结构和基本操作,并且正确实现了DFS和BFS两种遍历算法。
我们对不同规模的图进行了测试,并分析了算法的时间复杂度。
实验结果表明,邻接矩阵的存储结构在添加和删除节点时的时间复杂度较高,而在查找节点和边时的时间复杂度较低。
DFS和BFS的时间复杂度都为O(V+E),其中V表示节点数,E表示边数。
数据结构_图_采用邻接矩阵存储,构造无向图
1.采用邻接矩阵(邻接表)存储,构造无向图(网)输入:顶点数、边数、顶点信息、边信息输出:图的顶点,图的边邻接矩阵(数组表示法)处理方法:用一个一维数组存储图中顶点的信息,用一个二维数组(称为邻接矩阵)存储图中各顶点之间的邻接关系。
假设图G=(V,E)有n个顶点,则邻接矩阵是一个n×n 的方阵,定义为:如果(vi,vj)属于边集,则edges[i][j]=1,否则edges[i][j]=0。
邻接表存储的处理方法:对于图的每个顶点vi,将所有邻接于vi的顶点链成一个单链表,称为顶点vi的边表(对于有向图则称为出边表),所有边表的头指针和存储顶点信息的一维数组构成了顶点表。
程序代码:#include<iostream>using namespace std;#define MAX_VERTEX_NUM 20 //最大顶点个数#define OK 1typedef int Status;//图的数组(邻接矩阵)存储表示typedef struct ArcCell { // 弧的定义int adj; // VRType是顶点关系类型。
// 对无权图,用1或0表示相邻否;// 对带权图,则为权值类型。
int *info; // 该弧相关信息的指针} ArcCell, AdjMatrix[MAX_VERTEX_NUM][MAX_VERTEX_NUM];typedef struct { // 图的定义char vexs[MAX_VERTEX_NUM];//顶点向量AdjMatrix arcs; // 邻接矩阵int vexnum, arcnum; // 图的当前顶点数、弧数} MGraph;int LocateV ex(MGraph G, char v){int a;for (int i = 0; i <= G.vexnum; i++){if (G.vexs[i] == v)a= i;}return a;}Status CreateUDN(MGraph &G) { //采用邻接矩阵表示法,构造无向网Gint i, j, k, w;char v1, v2;cout <<"输入顶点数,边数:"<< endl;cin >> G.vexnum >> G.arcnum;//IncInfo为0,表示各弧无信息cout <<"各顶点分别为:"<< endl;for (i = 0; i<G.vexnum; i++)cin >> G.vexs[i]; //构造顶点向量for (i = 0; i<G.vexnum; i++) //初始化邻接矩阵for (j = 0; j<G.vexnum; j++){G.arcs[i][j].adj =NULL;}cout <<"顶点信息、边信息:"<< endl;for (k = 0; k<G.arcnum; k++) { //构造邻接矩阵cin >> v1 >> v2 >> w; //输入一条边依附的顶点及权值i = LocateV ex(G, v1); j = LocateV ex(G, v2);G.arcs[i][j].adj = w;G.arcs[j][i] = G.arcs[i][j];} return OK;} //CreateUDN (p162 算法7.2)Status printf1(MGraph G){cout <<"该图的顶点分别为:";for (int i = 0; i<G.vexnum; i++)cout << G.vexs[i] <<"";return OK;}Status printf2(MGraph G){cout <<"该图的边为:";for (int i = 1; i<G.vexnum; i++) //初始化邻接矩阵for (int j = 0; j<i; j++){if (G.arcs[i][j].adj !=NULL)cout << G.vexs[j]<< G.vexs[i] <<"," ;}return OK;}int main(){MGraph G;CreateUDN(G);printf1(G);cout << endl;printf2(G);cout << endl;system("pause");return 0;}。
3数据结构与算法实验报告-图
沈阳工程学院学生实验报告(课程名称:数据结构与算法)实验题目:图班级计算机121学号2012417116 姓名赵玉林地点F608 指导教师张欣实验日期: 2013 年11 月28 日一、实验目的1.掌握图的基本存储方法。
2.掌握有关图的操作算法并用高级语言实现。
3.熟练掌握图的两种搜索路径的遍历方法。
4.掌握图的有关应用。
二、实验环境Turbo C或是Visual C++三、实验内容与要求实验1 建立无向图的邻接矩阵或邻接表存储并输出本题给出了一个无向图的邻接矩阵存储表示,在此基础上稍加改动就可以实现有向图、无向图和有向网的邻接矩阵表示。
实验2 建立图的邻接矩阵或邻接表存储并在此基础上实现图的深度优先遍历和广度优先遍历图的广度优先遍历用非递归方法很容易理解,非递归方法需要辅助队列Q以及出队、入队函数。
四、实验过程及结果分析源代码:#include<stdio.h>#include<malloc.h>#define MAX_NUM 20#define OK 1#define ERROR -1typedef int ElemType;typedef char VertexType;typedef struct ArcNode{ //定义弧结点ElemType data;ArcNode *nextarc;}ArcNode,*ArcLink;typedef struct VNode{ //定义顶点结点VertexType data;ArcLink firstarc;}VNode,AdjList[MAX_NUM];typedef struct{AdjList vdata;int vexnum,arcnum;}ALGraph;//构建图的邻接表int Creategraph(ALGraph &G,int n){ ArcLink p;int e,i;char v,w;for(i=0;i<n;i++){G.vdata[i].data='A'+i;G.vdata[i].firstarc=NULL;}printf("输入边的个数:\n");scanf("%d",&e);for(i=0;i<e;i++){getchar();//接收scanf的回车符printf("请输入某边所依附的两个顶点用A--%C表示\n",'A'+n-1); scanf("%c%c",&v,&w);//fflush(stdin);printf("V=%c,W=%c,I=%d\n",v,w,i);p=(ArcLink )malloc(sizeof(ArcNode));p->data=(int)(w-'A'+1);printf("%d\n",p->data);p->nextarc=G.vdata[(int)(v-'A')].firstarc;G.vdata[(int)(v-'A')].firstarc=p;p=(ArcLink)malloc(sizeof(ArcNode));p->data=(int)(v-'A'+1);p->nextarc=G.vdata[(int)(w-'A')].firstarc;G.vdata[(int)(w-'A')].firstarc=p;}G.vexnum=n; G.arcnum=e;return OK;}//输出邻接表int printGraph(ALGraph G){ArcLink p;int i;for(i=0;i<G.vexnum;i++){printf("%2d %c",i,G.vdata[i]);for(p=G.vdata[i].firstarc;p!=NULL;p=p->nextarc){ printf("-->");printf("%d",p->data);}printf("\n");}return OK;}int main(){ALGraph G;int n;printf("请输入你要构建的无向图的顶点个数:\n"); scanf("%d",&n);Creategraph(G,n);printf("你所构建的无向图的邻接表如下所示:\n"); printGraph(G);return OK;}1-1建立无向图的顶点数1-2建立无向图的边数1-3建立无向图五、成绩评定优良中及格不及格出勤内容格式创新效果总评指导教师:年月日。
数据结构--图实验
XXXX学院计算机工程系
《数据结构》·实验报告
实验名称实验8、图实验实验时间
学生姓名班级学号
指导教师批阅教师成绩
实验目的:
1)掌握图的逻辑结构;
2)掌握图的邻接矩阵储存结构;
3)验证图邻接矩阵储存及其遍历操作的实现。
实验设备:
联网的PC机一台,安装有Windows操作系统
实验内容:
1)建立无向图的邻接矩阵储存;
2)对建立的无向图,进行深度优先遍历;
3)对建立的无向图,进行广度优先遍历。
实验步骤及实验结果记录:
1.在VC++编程环境下新建一个工程“邻接矩阵验证实验”,在该工程中新建一个头
文件Mgraph.h,该头文件包括无向图类Mgraph的定义
2.在工程“邻接矩阵验证实验”中新建一个源文件Mgraph.cpp,该文件包括类Mgraph 中成员函数的定义
在工程“邻接矩阵验证实验”中新建一个源程序文件MGraph_Mian.cpp,该文件包括主函数
实验总结:在本次的实验中我学到了图中的邻接矩阵是怎样实现的,但是还是表现出了自己的不足之处,我还是有很多的地方是不会的,在以后的学习中,我需要加倍的努力才行。
图的存储实验报告
图的存储实验报告图的存储实验报告引言在计算机科学领域中,图是一种重要的数据结构,用于描述对象之间的关系。
图的存储方式对于图的遍历、搜索和其他操作有着重要的影响。
本实验旨在探究不同的图存储方式,并比较它们在不同操作下的性能差异。
一、邻接矩阵存储方式邻接矩阵是一种常见的图存储方式,它使用二维数组来表示图中各个顶点之间的关系。
在邻接矩阵中,行和列分别代表图中的顶点,矩阵中的元素表示两个顶点之间的边的关系。
实验中,我们通过一个简单的例子来说明邻接矩阵的存储方式。
假设有一个无向图,其中包含5个顶点和6条边。
我们可以使用一个5x5的矩阵来表示这个图,矩阵中的元素为1表示两个顶点之间存在边,为0表示不存在边。
邻接矩阵的优点是可以快速判断两个顶点之间是否存在边,时间复杂度为O(1)。
然而,邻接矩阵的缺点是当图中的边数较少时,会造成存储空间的浪费。
此外,在图中顶点的增加和删除操作时,需要重新调整矩阵的大小,开销较大。
二、邻接表存储方式邻接表是另一种常见的图存储方式,它使用链表来表示图中各个顶点之间的关系。
在邻接表中,每个顶点都有一个链表,链表中存储了与该顶点相邻的顶点。
实验中,我们同样以一个简单的例子来说明邻接表的存储方式。
假设有一个有向图,其中包含4个顶点和5条边。
我们可以使用一个包含4个链表的数组来表示这个图,数组中的每个元素表示一个顶点,链表中的元素表示与该顶点相邻的顶点。
邻接表的优点是在图中边的数量较少时,可以节省存储空间。
此外,在图中顶点的增加和删除操作时,开销较小。
然而,邻接表的缺点是判断两个顶点之间是否存在边的时间复杂度较高,需要遍历链表,时间复杂度为O(顶点的度数)。
三、性能比较与结论通过实验,我们对比了邻接矩阵和邻接表两种图存储方式在不同操作下的性能差异。
在判断两个顶点之间是否存在边的操作中,邻接矩阵的时间复杂度为O(1),而邻接表的时间复杂度为O(顶点的度数)。
因此,在此操作下,邻接矩阵的性能更优。
数据结构与算法-图的邻接矩阵
实验报告实验日期:数据结构与算法课程:图的邻接矩阵实验名称:一、实验目的掌握图的邻接矩阵二、实验内容必做部分、给出图的邻接矩阵存储结构的类型定义。
1 -1。
v,返回其在vexs数组中的下标,否则返回2、实现LocateVex(G,v)操作函数:若找到顶点。
、实现算法7.2(构造无向网)3&G)Status CreateUDN(MGraph设计并实现无向网的输出算法,要求能显示顶点以及顶点之间的邻接关系(方式自定)4、并进行输出。
要求给出至少两组测试数据。
在主函数中调用CreateUDN创建一个无向网,5、选做部分类型)编写下述操作函数:基于图的邻接矩阵存储结构(即MGraph若找不到这样返回该邻接点在顶点数组中的下标;1个邻接点,1、求下标为v的顶点的第-1。
的邻接点,返回int FirstAdjVex(MGraph G,int v)的顶点的下一个邻接点,返回该邻接点的下标;若w求下标为v的顶点相对于下标为2、找不到这样的邻接点,返回-1。
int NextAdjVex(MGraph G,int v,int w)在主函数调用上述函数,给出测试结果。
三、实验步骤必做部分给出图的邻接矩阵存储结构的类型定义。
、1.2、实现LocateVex(G,v)操作函数:若找到顶点v,返回其在vexs数组中的下标,否则返回-1。
3、实现算法7.2(构造无向网)。
&G)CreateUDN(MGraph Status设计并实现无向网的输出算法,要求能显示顶点以及顶点之间的邻接关系(方式自定)、4.要求给出至少两组测试数据。
并进行输出。
、在主函数中调用CreateUDN创建一个无向网,5选做部分基于图的邻接矩阵存储结构(即MGraph类型)编写下述操作函数:1、求下标为v的顶点的第1个邻接点,返回该邻接点在顶点数组中的下标;若找不到这样的邻接点,返回-1。
int FirstAdjVex(MGraph G,int v)2、求下标为v的顶点相对于下标为w的顶点的下一个邻接点,返回该邻接点的下标;若找不到这样的邻接点,返回-1。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
数学与计算机学院课程设计说明书课程名称: 数据结构与算法课程设计课程代码: 6014389题目: 无向图的邻接矩阵存储结构年级/专业/班: 2018级软件4班学生姓名: 吴超学号: 312018*********开始时间: 2018年12月9日完成时间: 2018年12月30日课程设计成绩:学习态度及平时技术水平与实际创新<5)说明书<计算书、图纸、分析总分指导教师签名:年月日数据结构课程设计任务书学院名称:数学与计算机学院课程代码:__6014389______专业:软件工程年级: 2018一、设计题目无向图的邻接矩阵存储结构二、主要内容图是无向带权图,对下列各题,要求写一算法实现。
1)能从键盘上输入各条边和边上的权值;2)构造图的邻接矩阵和顶点集。
3)输出图的各顶点和邻接矩阵4)插入一条边5)删除一条边6)求出各顶点的度7)判断该图是否是连通图,若是,返回1;否则返回0.8)使用深度遍历算法,输出遍历序列。
三、具体要求及应提交的材料用C/C++语言编程实现上述内容,对每个问题写出一个算法实现,并按数学与计算机学院对课程设计说明书规范化要求,写出课程设计说明书,并提交下列材料:1>课程设计说明书打印稿一份2>课程设计说明书电子稿一份;3>源程序电子文档一份。
四、主要技术路线提示用一维数组存放图的顶点信息,二维数组存放各边信息。
五、进度安排按教案计划规定,数据结构课程设计为2周,其进度及时间大致分配如下:[1] 严蔚敏,吴伟民.数据结构.清华大学出版社出版。
[2] 严蔚敏,吴伟民. 数据结构题集(C语言版> .清华大学出版社.2003年5月。
[3]唐策善,李龙澎.数据结构(作C语言描述> .高等教育出版社.2001年9月[4] 朱战立.数据结构(C++语言描述><第二版本).高等出版社出版.2004年4月[5]胡学钢.数据结构(C语言版> .高等教育出版社.2004年8月指导教师签名日期年月日系主任审核日期年月日目录摘要随着计算机的普及,涉及计算机相关的科目也越来越普遍,其中数据结构是计算机专业重要的专业基础课程与核心课程之一,为适应我国计算机科学技术的发展和应用,学好数据结构非常必要,然而要掌握数据结构的知识非常难,所以对“数据结构”的课程设计比不可少。
本说明书是对“无向图的邻接矩阵存储结构”课程设计的说明。
首先是对需求分析的简要阐述,说明系统要完成的任务和相应的分析,并给出测试数据。
其次是概要设计,说明所有抽象数据类型的定义、主程序的流程以及各程序模块之间的层次关系,以及ADT描述。
然后是详细设计,描述实现概要设计中定义的基本功操作和所有数据类型,以及函数的功能及代码实现。
再次是对系统的调试分析说明,以及遇到的问题和解决问题的方法。
然后是用户使用说明书的阐述,然后是测试的数据和结果的分析,最后是对本次课程设计的结论。
关键词:网络化;计算机;对策;图;储存。
引言数据结构是计算机存储、组织数据的方式。
数据结构是指相互之间存在一种或多种特定关系的的集合。
通常情况下,精心选择的数据结构可以带来更高的运行或者存储。
数据结构往往同高效的检索算法和技术有关。
选择了数据结构,算法也随之确定,是数据而不是算法是系统构造的关键因素。
这种洞见导致了许多种方法和的出现,语言就是其中之一。
此次课程设计根据课堂讲授内容,下发任务书,要求学生完成相应系统,以消化课堂所讲解的内容;通过调试典型例题或习题积累调试C++程序从而获得数据结构的编程经验;通过完成此项课程设计,逐渐培养学生的编程能力、用计算机解决实际问题的能力,并充分理解图的矩阵储存方法。
此次课程设计题目为《无向图的邻接矩阵存储结构》,所利用工具为 Microsoft visual studio 2008.1需求分析随着计算机的普及,信息的存储逐渐和我们的日常生活变得密切起来,而数据的存储方式也多种多样,比如树、链表、数组、图等等。
为了充分体现图的矩阵储存结构的优势与功能,要求本系统应达到以下要求:1.图是无向带权图2.能从键盘上输入各条边和边上的权值;3.构造图的邻接矩阵和顶点集。
4.输出图的各顶点和邻接矩阵5.插入一条边6.删除一条边7.求出各顶点的度8.判断该图是否是连通图,若是,返回1;否则返回0.9.使用深度遍历算法,输出遍历序列。
1.1任务与分析邻接矩阵是表示图形中顶点之间相邻关系的矩阵。
设G=(V,E>是具有n个顶点的图,则G 的邻接矩阵是n阶方阵。
为了实现此算法,用一维数组a[]存放图的顶点信息,二维数组b[][]存放各边信息。
顶点或者边存在,则该数组应有值,通过此来进行建立、插入、删除。
其余方法也将能通过数组的特性来实现。
1.2测试数据1.建立图的矩阵存储结构,第一次建立连通图A1,第二次建立非连通图A2。
如下:图1.1测试数据2.选择输出图3.选择插入节点,插入44.选择插入边,在3,4节点中插入边,权值为555.选择深度优先搜索6.选择判断是否连通7.选择求最小生成树8.选择求各顶点的度9.选择退出,重新运行,此次建立A2的图,再次进行测试。
2 概要设计2.1 ADT描述ADT Glist{{VR}={图的顶点和边}VR={<v,w> | v,w∈V, <v,w>表示顶点v和w间的边;} 基本操作:初始化空图;输入建立图;深度优先遍历图;确定图中的顶点数目;确定图中边的数目;在图中插入一个顶点;在图中插入一条边;删除图中一个顶点删除图中的一条边;求顶点的度;求最小生成树;} ADT Graph。
2.2程序模块结构图2.1:模块结构2.2.1 结构体定义本系统未采用结构体方法,类的定义如下:定义顶点: nodecount,edgecount 边:已经分别存放顶点和边的两个数组: a[MaxNode]和b[MaxNode][MaxNode]。
其余成员函数均以public形式声明。
在邻接矩阵表示的图中,顶点信息用一维数组表示a[]。
在简单情况下可省略,仅以下标值代表顶点序号。
若需要,顶点信息更加丰富。
边<或弧)信息用二维数组表示b[ ][ ],这也是邻接矩阵。
包含边的权值。
在类中数据成员有4个,重要的是邻接矩阵Edge[ ][ ]、总边数edgecount和顶点数nodecount。
class Graph1{private:int nodecount。
//节点int edgecount。
//边int a[MaxNode]。
//顶点信息组//set<int> a。
int b[MaxNode][MaxNode]。
//权值信息组public:Graph1(int>。
//构造函数int getNodeCount(>。
//当前的节点数int getEdgeCount(>。
//当前的边数void insertNode(int>。
//插入一个节点void isertEdge(int ,int ,int>。
//插入一条边void deleteEdge(int,int>。
//删除一条边bool isliantong(>。
//判断是否连通int getWeight(int,int>。
//获得某条边的权值int Depth(int >。
//深度遍历准备,用于建立顶点访问数组和记录所访问顶点个数void Depth(int v,int visited[],int &n>。
//深度遍历void outDu(Graph1 G>。
//输出节点个数void PrintOut(Graph1 G> 。
//输出图void CreatG(int n,int e>。
//建立图}。
2.3各功能模块以下将以注释形式为每个函数的功能进行声明:构造函数:Graph1(int> 用于初始化图get函数:int getNodeCount(>。
得到当前的节点数get函数:int getWeight(int,int>。
获得某条边的权值get函数:int getEdgeCount(>。
得到当前的边数插入函数:void insertNode(int>。
插入一个节点插入函数:void isertEdge(int ,int ,int>。
插入一条边删除函数:void deleteEdge(int,int>。
删除一条边判断函数:bool isliantong(>。
判断是否连通遍历函数1:int Depth(int >。
//深度遍历准备,用于建立顶点访问数组和记录所访问顶点个数遍历函数2:void Depth(int v,int visited[],int &n>。
//深度遍历求度函数:void outDu(Graph1 G>。
输出节点个数输出函数:void PrintOut(Graph1 G> 。
输出图构建函数:void CreatG(int n,int e>。
建立图3 详细设计3.1类的定义class Graph1{private:int nodecount。
//节点int edgecount。
//边int a[MaxNode]。
//顶点信息组//set<int> a。
int b[MaxNode][MaxNode]。
//权值信息组public:Graph1(int>。
//构造函数int getNodeCount(>。
//当前的节点数int getEdgeCount(>。
//当前的边数void insertNode(int>。
//插入一个节点void isertEdge(int ,int ,int>。
//插入一条边void deleteEdge(int,int>。
//删除一条边void prim(int>。
//生成最小树bool isliantong(>。
//判断是否连通int getWeight(int,int>。
//获得某条边的权值int Depth(int >。
//深度遍历准备,用于建立顶点访问数组和记录所访问顶点个数void Depth(int v,int visited[],int &n>。
//深度遍历void outDu(Graph1 G>。
//输出节点个数void PrintOut(Graph1 G> 。
//输出图void CreatG(int n,int e>。
//建立图}。
3.2 初始化初始化邻接矩阵以及有关参数,通过for循环将数组的值都初始化为0,使之成为一个空图。