数据结构实验十一:图实验
数据结构图的实验报告
数据结构图的实验报告数据结构图的实验报告引言:数据结构图是计算机科学中重要的概念之一。
它是一种用图形表示数据元素之间关系的数据结构,广泛应用于算法设计、程序开发和系统优化等领域。
本实验报告旨在介绍数据结构图的基本原理、实验过程和结果分析。
一、实验目的本次实验的主要目的是掌握数据结构图的基本概念和操作方法,以及通过实验验证其在解决实际问题中的有效性。
具体而言,我们将通过构建一个社交网络关系图,实现对用户关系的管理和分析。
二、实验方法1. 确定数据结构在本次实验中,我们选择了无向图作为数据结构图的基础。
无向图由顶点集和边集组成,每条边连接两个顶点,且没有方向性。
2. 数据输入为了模拟真实的社交网络,我们首先需要输入一组用户的基本信息,如姓名、年龄、性别等。
然后,根据用户之间的关系建立边,表示用户之间的交流和联系。
3. 数据操作基于构建好的数据结构图,我们可以进行多种操作,如添加用户、删除用户、查询用户关系等。
这些操作将通过图的遍历、搜索和排序等算法实现。
三、实验过程1. 数据输入我们首先创建一个空的无向图,并通过用户输入的方式逐步添加用户和用户关系。
例如,我们可以输入用户A和用户B的姓名、年龄和性别,并建立一条边连接这两个用户。
2. 数据操作在构建好数据结构图后,我们可以进行多种操作。
例如,我们可以通过深度优先搜索算法遍历整个图,查找与某个用户具有特定关系的用户。
我们也可以通过广度优先搜索算法计算某个用户的社交网络影响力,即与该用户直接或间接相连的其他用户数量。
3. 结果分析通过实验,我们可以观察到数据结构图在管理和分析用户关系方面的优势。
它能够快速地找到用户之间的关系,帮助我们了解用户的社交网络结构和影响力。
同时,数据结构图也为我们提供了一种可视化的方式来展示用户之间的关系,使得分析更加直观和易于理解。
四、实验结果通过实验,我们成功构建了一个社交网络关系图,并实现了多种数据操作。
我们可以根据用户的姓名、年龄和性别等信息进行查询,也可以根据用户之间的关系进行遍历和排序。
数据结构实验报告-图的遍历
数据结构实验报告实验:图的遍历一、实验目的: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)深度优先遍历和广度优先遍历都有着各自的优点,通过程序逐步调试,可以慢慢的理解这两种遍历方法的内涵和巧妙之处。
数据结构实验报告--图
数据结构实验报告--图
数据结构实验报告--图
1、实验目的
本实验主要旨在通过实践操作,深入理解图这种数据结构的基本概念、性质和基本操作,掌握图的存储结构与常见算法。
2、实验环境
本次实验使用编程语言C++,在Windows平台下进行开发和运行。
3、实验内容
3.1 图的定义与基本概念
在本章中,我们将介绍图的基本概念,包括有向图与无向图、顶点与边、度与入度出度、连通性等。
3.2 图的存储结构
在本章中,我们将介绍图的几种存储结构,包括邻接矩阵、邻接表和十字链表,以及它们的优缺点和适用场景。
3.3 图的遍历
在本章中,我们将介绍图的两种常用的遍历算法,即深度优先搜索(DFS)和广度优先搜索(BFS),并分别给出它们的实现代码和应用场景。
3.4 最短路径
在本章中,我们将介绍图的最短路径问题,包括单源最短路径和全源最短路径。
我们将使用Dijkstra算法和Floyd-Warshall算法来解决这些问题,并给出它们的实现代码和应用场景。
3.5 最小树
在本章中,我们将介绍图的最小树问题,即找到一棵树使得树上的边的权值之和最小。
我们将使用Prim算法和Kruskal算法来解决这个问题,并给出它们的实现代码和应用场景。
4、实验步骤和结果
在本章中,我们将详细介绍实验的具体步骤,并给出实验结果的详细分析和说明。
5、实验总结
在本章中,我们将对整个实验进行总结,总结实验中遇到的问题、解决方案和经验教训。
6、附件
本实验报告所涉及的附件包括实验代码和运行结果的截图。
7、法律名词及注释
本文所涉及的法律名词和注释详见附件中的相关文件。
数据结构实验报告图的应用
实验题目:图的应用一、实验目的和任务1 掌握图的邻接表和邻接矩阵存储;2 掌握图的拓扑排序算法;二、实验内容及原理1以下两项内容选做一项。
2 请按照书中介绍的拓扑排序算法,完成P303页第5题。
3 给定某一个图,完成其深度优先搜索遍历和广度优先搜索遍历,每种遍历都必须在邻接矩阵和邻接表中完成。
四、实验数据及程序代码#include <iostream.h>#include <stdlib.h>#include <strstrea.h>#include <string.h>#include <stdio.h>const int MaxVertexNum=10;typedef int WeightType;struct edgenode{int adjvex;WeightType weight;edgenode*next;};typedef edgenode *adjlist[MaxVertexNum];void InitAdjoin(adjlist GL)//初始化{for(int i=0;i<MaxVertexNum;i++)GL[i]=NULL;}void CreatAdjoin(adjlist GL,int n,char*s,int k1,int k2)//生成邻接表{istrstream sin(s);char c1,c2,c3;WeightType w;edgenode*p;sin>>c1;if(k2==0){do{sin>>c1>>i>>c2>>j>>c3;p=new edgenode;p->adjvex=j;p->weight=1;p->next=GL[i];GL[i]=p;if(k1==0){p=new edgenode;p->adjvex=i;p->weight=1;p->next=GL[j];GL[j]=p;}sin>>c1;}while(c1==',');}else{do{sin>>c1>>i>>c2>>j>>c3>>w;p=new edgenode;p->adjvex=j;p->weight=w;p->next=GL[i];GL[i]=p;if(k1==0){p=new edgenode;p->adjvex=i;p->weight=w;p->next=GL[j];GL[j]=p;}sin>>c1;}while(c1==',');}}void PrintAdjion(adjlist GL, int n,int k1, int k2) {edgenode*p;cout<<"V={";for(i=0; i<n-1; i++) cout<<i<<',';cout<<n-1<<'}'<<endl;cout<<"E={";for(i=0;i<n;i++){if(k2==0){p=GL[i];while(p){j=p->adjvex;if(k1==0){if(i<j) cout<<'('<<i<<','<<j<<')'<<',';}elsecout<<'<'<<i<<","<<j<<'>'<<',';p=p->next;}}else{p=GL[i];while(p){j=p->adjvex;if(k1==0){if(i<j) cout<<'('<<i<<','<<j<<')'<<p->weight<<',';}elsecout<<'<'<<i<<','<<j<<'>'<<p->weight<<',';p=p->next;}}}cout<<'}'<<endl;}void Toposort(adjlist GL , int n){int i,j,k,top,m=0;edgenode*p;int*d=new int[n];for(i=0;i<n;i++) d[i]=0;for(i=0;i<n;i++){p=GL[i];while(p!=NULL){j=p->adjvex;d[i]++;p=p->next;//cout<<j;}}top=-1;for(i=0;i<n;i++)if(d[i]==0){d[i]=top; top=i;}while(top!=-1){j=top;top=d[top];cout<<j<<' ';m++;p=GL[j];while(p!=NULL){k=p->adjvex;d[k]--;if(d[k]==0){d[k]=top;top=k;}p=p->next;}}cout<<endl;cout<<top<<endl;cout<<m<<endl;cout<<n<<endl;if(m<n) cout<<"The network has a cycle!"<<endl;delete []d;}void main(){int n,k1,k2;cout<<"输入待处理图的顶点数:";cin>>n;cout<<"输入图的有无向和有无权选择(0为无,非0为有):";cin>>k1>>k2;adjlist gl;InitAdjoin(gl);cout<<"输入图的边集:";FILE *p;p=fopen("d:\\1.txt","r+");char *a=new char[100];while (!feof(p)){fscanf(p,"%s ",a);cout<<a;}cout<<endl;//cin>>a;CreatAdjoin(gl,n,a,k1,k2);Toposort(gl,n);}五、实验数据分析及处理六、实验结论与感悟(或讨论)图的邻接矩阵,邻接表和边集数组表示各有利弊,具体运用时,要根据图的稠密和稀疏程度以及算法的要求进行选择。
数据结构图实验报告
数据结构图实验报告数据结构图实验报告1. 引言数据结构是计算机科学中的重要概念之一,它研究数据的组织、存储和管理方式。
图作为一种重要的数据结构,广泛应用于各个领域,如网络拓扑、社交网络分析等。
本实验旨在通过实际操作,深入理解数据结构图的基本概念和操作。
2. 实验目的本实验的主要目的是掌握图的基本概念和相关操作,包括图的创建、遍历、搜索和最短路径算法等。
3. 实验环境本实验使用C++语言进行编程,采用图的邻接矩阵表示法进行实现。
4. 实验内容4.1 图的创建在实验中,我们首先需要创建一个图。
通过读取输入文件中的数据,我们可以获得图的顶点数和边数,并根据这些信息创建一个空的图。
4.2 图的遍历图的遍历是指从图的某个顶点出发,按照一定的规则依次访问图中的其他顶点。
常用的图的遍历算法有深度优先搜索(DFS)和广度优先搜索(BFS)。
我们可以通过实验来比较这两种遍历算法的效率和应用场景。
4.3 图的搜索图的搜索是指从图的某个顶点出发,找到与之相关的特定顶点或边。
常用的图的搜索算法有深度优先搜索和广度优先搜索。
在实验中,我们可以通过输入特定的顶点或边,来观察图的搜索算法的执行过程和结果。
4.4 图的最短路径算法图的最短路径算法是指在图中找到两个顶点之间的最短路径。
常用的最短路径算法有迪杰斯特拉算法和弗洛伊德算法。
通过实验,我们可以比较这两种算法的执行效率和应用场景。
5. 实验结果与分析通过实验,我们可以得到以下结论:- 图的邻接矩阵表示法在创建和操作图的过程中具有较高的效率。
- 深度优先搜索算法适用于查找图中的连通分量和回路等问题。
- 广度优先搜索算法适用于查找图中的最短路径和最小生成树等问题。
- 迪杰斯特拉算法适用于求解单源最短路径问题,而弗洛伊德算法适用于求解多源最短路径问题。
6. 实验总结通过本次实验,我们深入学习了数据结构图的基本概念和相关操作。
图作为一种重要的数据结构,具有广泛的应用价值。
在今后的学习和工作中,我们可以运用所学的知识,解决实际问题,提高工作效率。
数据结构实验报告—图
《算法与数据结构》课程实验报告一、实验目的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,用以存储图中的边,其矩阵元素个数取决于顶点个数,与边数无关。
数据结构实验———图实验报告
数据结构实验报告目的要求1.掌握图的存储思想及其存储实现。
2.掌握图的深度、广度优先遍历算法思想及其程序实现。
3.掌握图的常见应用算法的思想及其程序实现。
实验容1.键盘输入数据,建立一个有向图的邻接表。
2.输出该邻接表。
3.在有向图的邻接表的基础上计算各顶点的度,并输出。
4.以有向图的邻接表为基础实现输出它的拓扑排序序列。
5.采用邻接表存储实现无向图的深度优先递归遍历。
6.采用邻接表存储实现无向图的广度优先遍历。
7.在主函数中设计一个简单的菜单,分别调试上述算法。
源程序:主程序的头文件:队列#include <stdio.h>#include <stdlib.h>#define TRUE 1#define FALSE 0#define OK 1#define ERROR 0#define OVERFLOW -2typedef int QElemT ype;typedef struct QNode{ //队的操作QElemT ype data;struct QNode *next;}QNode,*QueuePtr;typedef struct {QueuePtr front;QueuePtr rear;}LinkQueue;void InitQueue(LinkQueue &Q){ //初始化队列Q.front =Q.rear =(QueuePtr)malloc(sizeof(QNode));if(!Q.front) exit(OVERFLOW); //存储分配失败Q.front ->next =NULL;}int EnQueue(LinkQueue &Q,QElemT ype e) //插入元素e为Q的新的队尾元素{QueuePtr p;p=(QueuePtr)malloc(sizeof(QNode));if(!p) exit(OVERFLOW);p->data=e;p->next=NULL;Q.rear->next=p;Q.rear =p;return OK;}int DeQueue(LinkQueue &Q,QElemT ype &e) //删除Q的队头元素,用e返回其值{ if(Q.front ==Q.rear ) return ERROR;QueuePtr p;p=Q.front ->next;e=p->data;Q.front->next=p->next ;if(Q.rear==p) Q.rear =Q.front ;free(p);return OK;}主程序:#include <stdio.h>#include<stdlib.h>#include"duilie.h"#define TRUE 1#define FALSE 0#define Status int#define MAX_VERTEX_NUM 8 /*顶点最大个数*/#define VertexType char /*顶点元素类型*/enum BOOlean {False,True};BOOlean visited[MAX_VERTEX_NUM]; //全局变量——访问标志数组typedef struct ArcNode{int adjvex;struct ArcNode *nextarc;int weight; /*边的权*/}ArcNode; /*表结点*/typedef struct VNode{ int degree,indegree;/*顶点的度,入度*/VertexType data;ArcNode *firstarc;}VNode/*头结点*/,AdjList[MAX_VERTEX_NUM];typedef struct{ AdjList vertices;int vexnum,arcnum;/*顶点的实际数,边的实际数*/}ALGraph;//建立图的邻接表void creat_link(ALGraph *G){ int i,j;ArcNode *s;printf("请依次输入顶点数、边数:");scanf("%d%d",&G->vexnum,&G->arcnum);for (i=0;i<G->vexnum;i++){ G->vertices[i].data='A'+i;G->vertices[i].firstarc=NULL;}for (i=0;i<G->vexnum;){ printf("请输入顶点的数组坐标(若退出,请输入-1):");scanf("%d",&i);if(i==-1) break;printf("请输入顶点所指向下一个顶点的数组坐标:");scanf("%d",&j);s=(ArcNode *)malloc(sizeof(ArcNode));s->adjvex=j;s->nextarc=G->vertices[i].firstarc;G->vertices[i].firstarc=s;}}// 输出邻接表void visit(ALGraph G){ int i;ArcNode *p;printf("%4s%6s%18s\n","NO","data","adjvexs of arcs");for (i=0;i<G.vexnum;i++){printf("%4d%5c ",i,G.vertices[i].data);for(p=G.vertices[i].firstarc;p;p=p->nextarc)printf("%3d",p->adjvex);printf("\n");}}// 计算各顶点的度及入度void cacu(ALGraph *G){ArcNode *p;int i;for (i=0;i<G->vexnum;i++){G->vertices[i].degree=0;G->vertices[i].indegree=0;}//度与初度初始化为零for (i=0;i<G->vexnum;i++)for(p=G->vertices[i].firstarc;p;p=p->nextarc){G->vertices[i].degree++;G->vertices[p->adjvex].degree++;G->vertices[p->adjvex].indegree++;}}void print_degree(ALGraph G){int i;printf("\n Nom data degree indegree\n");for (i=0;i<G.vexnum;i++)printf("\n%4d%5c%7d%8d",i,G.vertices[i].data,G.vertices[i].degree,G.vertices[i].indegree);printf("\n");}// 拓扑排序Status T opologiSort(ALGraph G){int i,count,top=0,stack[50];ArcNode *p;cacu(&G);print_degree(G);printf("\nT opologiSort is \n");for(i=0;i<G.vexnum;i++)if(!G.vertices[i].indegree) stack[top++]=i;count=0;while(top!=0){i=stack[--top];if (count==0) printf("%c",G.vertices[i].data);else printf("-->%c",G.vertices[i].data);count++;for(p=G.vertices[i].firstarc;p;p=p->nextarc)if (!--G.vertices[p->adjvex].indegree)stack[top++]=p->adjvex;}if (count<G.vexnum)return(FALSE); else return(TRUE);}//在图G中寻找第v个顶点的第一个邻接顶点int FirstAdjVex(ALGraph G,int v){if(!G.vertices[v].firstarc) return 0;else return(G.vertices[v].firstarc->adjvex);}//在图G中寻找第v个顶点的相对于u的下一个邻接顶点int NextAdjVex(ALGraph G,int v,int u){ArcNode *p;p=G.vertices[v].firstarc;while(p->adjvex!=u) p=p->nextarc; //在顶点v的弧链中找到顶点u if(p->nextarc==NULL) return 0; //若已是最后一个顶点,返回0 else return(p->nextarc->adjvex); //返回下一个邻接顶点的序号}//采用邻接表存储实现无向图的深度优先递归遍历void DFS(ALGraph G,int i){ int w;visited[i]=True; //访问第i个顶点printf("%d->",i);for(w=FirstAdjVex(G,i);w;w=NextAdjVex(G,i,w))if(!visited[w]) DFS(G,w); //对尚未访问的邻接顶点w调用DFS}void DFSTraverse(ALGraph G){ int i;printf("DFSTraverse:");for(i=0;i<G.vexnum;i++) visited[i]=False; //访问标志数组初始化for(i=0;i<G.vexnum;i++)if(!visited[i]) DFS(G,i); //对尚未访问的顶点调用DFS}//按广度优先非递归的遍历图G,使用辅助队列Q和访问标志数组visitedvoid BFSTraverse(ALGraph G){int i,u,w;LinkQueue Q;printf("BFSTreverse:");for(i=0;i<G.vexnum;i++) visited[i]=False; //访问标志数组初始化InitQueue(Q); //初始化队列for(i=0;i<G.vexnum;i++)if(!visited[i]){visited[i]=True; //访问顶点iprintf("%d->",i);EnQueue(Q,i); //将序号i入队列while(!(Q.front ==Q.rear)) //若队列不空,继续{DeQueue(Q,u); //将队头元素出队列并置为ufor(w=FirstAdjVex(G,u);w;w=NextAdjVex(G,u,w))if(!visited[w]) //对u的尚未访问的邻接顶点w进行访问并入队列{ visited[w]=True;printf("%d->",w);EnQueue(Q,w);}}}}void main(){ALGraph G;int select;printf(" 图的有关操作实验\n ");do{printf("\n1 创建一个有向图的邻接表 2 输出该邻接表\n");printf("3.输出该有向图的度和入度 4.输出该有向图拓扑排序序列\n");printf("5.创建一个无向图的邻接表 6.深度优先递归遍历该无向图\n");printf("7.广度优先遍历该无向图0.退出\n");printf("请输入选择:");scanf("%d",&select);switch(select){case 1:printf("\n创建一个有向图的邻接表:\n");creat_link(&G);break;case 2:printf("\n输出该邻接表:\n");visit(G);break;case 3:printf("\n输出该有向图的度和入度:\n");cacu(&G);print_degree(G);break;case 4:printf("\n输出该有向图拓扑排序序列:\n");if(!T opologiSort(G))printf("T oposort is not success!");break;case 5:printf("\n创建一个无向图的邻接表: \n");creat_link(&G);break;case 6:printf("\n深度优先递归遍历该无向图: \n");DFSTraverse(G);break;case 7:printf("\n广度优先遍历该无向图:\n");BFSTraverse(G);break;case 0:break;default:printf("输入选项错误!重新输入!\n");}}while(select);}运行结果截图:1.主菜单界面:2.创建一个有向图的领接表3.输出该邻接表4. 在有向图的邻接表的基础上计算各顶点的度,并输出。
数据结构实验十一-图的应用实验
实验报告十一图的应用实验班级:姓名:学号:专业:一、实验目的:1、掌握图的存储结构及创建算法。
2、掌握图的最小生成树prime算法.3、掌握图的最短路径Dijkstra、Floyd算法。
4、二、实验内容:[实现提示] (同时可参见教材及ppt上的算法)函数、类名称等可自定义,部分变量请加上学号后3位。
也可自行对类中所定义的操作进行扩展。
所加载的库函数或常量定义及类的定义:#include<iostream>using namespace std;const int MaxSize=12;const int INFINITY=65535;template <class T>class Mgraph{public:Mgraph(T a[],int n,int e);void PGraph();void Prim(int n);private:T vertex[MaxSize];int a[MaxSize];int arc[MaxSize][MaxSize];int vertexNum,arcNum;void createUG(T a[],int n,int e);void createUW(T a[],int n,int e);void createHG(T a[],int n,int e);void createHW(T a[],int n,int e);};struct bian{int nearvex;};1、邻接矩阵存储结构类定义与实现。
自定义如下:template <class T>void Mgraph<T>::createUG(T a[],int n,int e){vertexNum=n;arcNum=e;int i,j,k;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<<"请输入第"<<k+1<<"条边(格式:顶点1 顶点2):"; cin>>i>>j;arc[i][j]=1;arc[j][i]=1;}}template <class T>void Mgraph<T>::createUW(T a[],int n,int e){int w;vertexNum=n;arcNum=e;int i,j,k;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]=INFINITY;for (k=0; k<arcNum; k++){cout<<"请输入第"<<k+1<<"条边(格式:顶点1 顶点2 权值):"; cin>>i>>j>>w;arc[i][j]=w;arc[j][i]=w;}}template<class T>void Mgraph<T>::createHG(T a[],int n,int e){vertexNum=n;arcNum=e;int i,j,k;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<<"请输入第"<<k+1<<"条边(格式:顶点1 顶点2):"; cin>>i>>j;arc[i][j]=1;}}template<class T>void Mgraph<T>::createHW(T a[],int n,int e){int w;vertexNum=n;arcNum=e;int i,j,k;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]=INFINITY;for (k=0; k<arcNum; k++){cout<<"请输入第"<<k+1<<"条边(格式:顶点1 顶点2 权值):"; cin>>i>>j>>w;arc[i][j]=w;}}template <class T>void Mgraph<T>::PGraph(){int i,j;for(i=0;i<vertexNum;i++){for(j=0;j<vertexNum;j++)cout<<arc[i][j]<<ends;cout<<endl;}}template<class T>Mgraph<T>::Mgraph(T a[],int n,int e){int i;cout<<"若创建无向网1,无向图2,有向网3,有向图4"; cin>>i;switch(i){case 1: createUW(a,n,e);break;case 2: createUG(a,n,e);break;case 3: createHW(a,n,e);break;case 4: createHG(a,n,e);break;}}2、最小生成树prime算法[实现提示] (同时可参见教材p175页算法)库函数和常量定义:template<class T>void Mgraph<T>::Prim(int n){float min;int v,i,j;int b[MaxSize];bian *line=new bian[n];for(i=1;i<n;i++){b[i]=arc[0][i];line[i].nearvex=0;}for(i=1;i<n;i++)cout<<b[i]<<endl;b[0]=0;line[0].nearvex=-1;for(i=1;i<n;i++){min=INFINITY;v=0;for(j=0;j<n;j++)if(b[j]!=0&&b[j]<min){v=j;min=b[j];}if(v){a[v]=b[v];b[v]=0;for(j=0;j<n;j++)if(b[j]!=0&&arc[v][j]<b[j]){b[j]=arc[v][j];line[j].nearvex=v;}}}for(j=1;j<n;j++)cout<<"从"<<j<<"到"<<line[j].nearvex<<"距离为"<<a[j]<<endl; }int main(){int a[5]={1,2,3,4,5};Mgraph<int> picture(a,5,8);int b[5]={0,0,0,0,0};picture.Prim(5);return 0;}(1)图的储结构定义:自定义如下:(可自已定义)(2)prime算法测试结果粘贴如下:3、最短路径算法[实现提示] (同时可参见教材p187-192页算法)库函数和常量定义:#include<iostream>using namespace std;const int MaxSize=12;const int INFINITY=65535;template <class T>class Mgraph{public:Mgraph(T a[],int n,int e);void PGraph();void ShortestPath(int n,int v);private:T vertex[MaxSize];int arc[MaxSize][MaxSize];int vertexNum,arcNum;void createUG(T a[],int n,int e);void createUW(T a[],int n,int e);void createHG(T a[],int n,int e);void createHW(T a[],int n,int e);float *dist;int *path;int *s;};template <class T>void Mgraph<T>::createUG(T a[],int n,int e){vertexNum=n;arcNum=e;int i,j,k;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<<"请输入第"<<k+1<<"条边(格式:顶点1 顶点2):"; cin>>i>>j;arc[i][j]=1;arc[j][i]=1;}}template <class T>void Mgraph<T>::createUW(T a[],int n,int e){int w;vertexNum=n;arcNum=e;int i,j,k;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]=INFINITY;for (k=0; k<arcNum; k++){cout<<"请输入第"<<k+1<<"条边(格式:顶点1 顶点2 权值):"; cin>>i>>j>>w;arc[i][j]=w;arc[j][i]=w;}}template<class T>void Mgraph<T>::createHG(T a[],int n,int e){vertexNum=n;arcNum=e;int i,j,k;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<<"请输入第"<<k+1<<"条边(格式:顶点1 顶点2):"; cin>>i>>j;arc[i][j]=1;}}template<class T>void Mgraph<T>::createHW(T a[],int n,int e){int w;vertexNum=n;arcNum=e;int i,j,k;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]=INFINITY;for (k=0; k<arcNum; k++){cout<<"请输入第"<<k+1<<"条边(格式:顶点1 顶点2 权值):"; cin>>i>>j>>w;arc[i][j]=w;}}template <class T>void Mgraph<T>::PGraph(){int i,j;for(i=0;i<vertexNum;i++){for(j=0;j<vertexNum;j++)cout<<arc[i][j]<<ends;cout<<endl;}}template<class T>Mgraph<T>::Mgraph(T a[],int n,int e){int i;cout<<"若创建无向网1,无向图2,有向网3,有向图4";cin>>i;switch(i){case 1: createUW(a,n,e);break;case 2: createUG(a,n,e);break;case 3: createHW(a,n,e);break;case 4: createHG(a,n,e);break;}}(1)从某个源点到其余各顶点的最短路径(Dijkstra)template<class T>void Mgraph<T>::ShortestPath(int n,int v){float min;int u;dist=new float[n];s=new int[n];path=new int[n];for(int i=0;i<n;i++){dist[i]=arc[i][v];s[i]=0;if(i!=v&&dist[i]<INFINITY)path[i]=v;elsepath[i]=-1;}s[v]=1;for(int j=0;j<n-1;j++){min=INFINITY;u=v;if(!s[j]&&dist[j]<min){u=j;min=dist[j];}s[u]=1;for(int w=0;w<n;w++)if(!s[w]&&dist[u]+arc[u][w]<dist[w]){dist[w]=dist[u]+arc[u][w];path[w]=u;}}for(i=0;i<n;i++){if(dist[i]!=INFINITY){j=i;cout<<v<<"到"<<i<<"的最短距离为"<<dist[i]<<endl; cout<<"最短路程为";while(j!=1){cout<<path[j];j=path[j];}}cout<<endl;}}测试结果粘贴如下:(2)每一对顶点之间的最短路径template<class T>void Mgraph<T>::Floyd(int n) {int a[MaxSize][MaxSize];for(int i=0;i<n;i++)for(int j=0;j<n;j++){a[i][j]=arc[i][j];if(i!=j&&a[i][j]<INFINITY)path[i][j]=i;elsepath[i][j]=-1;}for(int k=0;k<n;k++)for(int i=0;i<n;i++)for(int j=0;j<n;j++){if(i==j)a[i][j]=0;elseif(a[i][k]+a[k][j]<a[i][j]) {a[i][j]=a[i][k]+a[k][j];path[i][j]=path[k][j];}}for(i=0;i<n;i++)for(int j=0;j<n;j++)cout<<"从"<<i<<"到"<<j<<"的最短路径为"<<a[i][j]<<endl;}测试结果粘贴如下:三、实验心得(含上机中所遇问题的解决办法,所使用到的编程技巧、创新点及编程的心得)。
数据结构 图实验报告
数据结构图实验报告数据结构图实验报告引言:数据结构是计算机科学中非常重要的一个概念,它用于存储和组织数据,使得数据的操作更加高效和方便。
图是一种常见的数据结构,它由节点和边组成,用于表示各种实际问题中的关系和连接。
本实验旨在通过实际操作,深入理解图的基本概念和常见操作。
实验目的: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表示边数。
数据结构与算法实验——图的
数据结构与算法实验——图的数据结构与算法实验——图的遍历与最短路径算法一、引言在计算机科学中,图是一种非常重要的数据结构,用于表示对象之间的关系。
图的遍历与最短路径算法是图算法中的两个基本问题,对于解决实际问题非常有用。
本文将介绍图的遍历和最短路径算法的原理和实现方法,并通过实验验证其正确性和效率。
二、图的遍历算法图的遍历是指从图中的某个顶点出发,按照某种策略依次访问图中的所有顶点,确保每个顶点都被访问到。
常见的图的遍历算法有深度优先搜索(DFS)和广度优先搜索(BFS)。
1. 深度优先搜索(DFS)深度优先搜索是一种递归的遍历算法,它从图中的某个顶点开始,沿着一条路径一直向下遍历,直到不能再继续为止,然后回溯到前一个顶点,继续遍历其他路径。
DFS的实现可以用递归或者栈来实现。
2. 广度优先搜索(BFS)广度优先搜索是一种非递归的遍历算法,它从图中的某个顶点开始,先访问该顶点,然后依次访问该顶点的所有邻接顶点,再依次访问邻接顶点的邻接顶点,以此类推。
BFS的实现可以用队列来实现。
三、最短路径算法最短路径算法是用于求解图中两个顶点之间最短路径的问题。
常见的最短路径算法有迪杰斯特拉算法(Dijkstra)和弗洛伊德算法(Floyd-Warshall)。
1. 迪杰斯特拉算法(Dijkstra)迪杰斯特拉算法是一种贪心算法,用于解决单源最短路径问题。
它从起始顶点开始,逐步确定到达其他顶点的最短路径,直到找到目标顶点的最短路径为止。
迪杰斯特拉算法的实现需要使用优先队列来选择距离起始顶点最近的顶点。
2. 弗洛伊德算法(Floyd-Warshall)弗洛伊德算法是一种动态规划算法,用于解决全源最短路径问题。
它通过逐步更新顶点之间的最短路径长度来求解所有顶点之间的最短路径。
弗洛伊德算法的实现需要使用二维数组来存储顶点之间的最短路径长度。
四、实验设计与结果分析为了验证图的遍历和最短路径算法的正确性和效率,我们设计了以下实验:1. 实验一:图的遍历算法比较在这个实验中,我们使用不同规模的图,比较DFS和BFS的遍历效率。
图形数据结构实验
图形数据结构实验1. 实验目的通过本实验,使学生掌握图这种数据结构的基本概念和基本算法,提高编程能力,为后续课程学习和实际应用打下基础。
2. 实验环境•编程语言:Java•开发工具:Eclipse/IntelliJ IDEA•硬件环境:计算机3. 实验内容3.1 实验原理图是一种复杂的数据结构,用于表示元素之间的相互关系。
图由顶点(节点)集合和边集合组成。
图的表示方法有邻接矩阵和邻接表两种。
3.2 实验任务1.实现图的邻接矩阵表示法;2.实现图的邻接表表示法;3.实现图的深度优先搜索(DFS)算法;4.实现图的广度优先搜索(BFS)算法;5.实现图的最短路径算法(如Dijkstra算法)。
4. 实验步骤4.1 创建图类首先,创建一个图类,包含顶点(节点)和边的基本操作。
```javaclass Graph {private int numVertices; // 顶点数量private int[][] adjMatrix; // 邻接矩阵public Graph(int numVertices) {this.numVertices = numVertices;adjMatrix = new int[numVertices][numVertices]; // 省略其他方法...4.2 邻接矩阵表示法实现邻接矩阵的初始化、添加边、删除边等操作。
```java// 初始化邻接矩阵public void initAdjMatrix() {for (int i = 0; i < numVertices; i++) {for (int j = 0; j < numVertices; j++) {if (i == j) {adjMatrix[i][j] = 0;} else {adjMatrix[i][j] = INFINITY;public void addEdge(int v1, int v2) {adjMatrix[v1][v2] = 1;adjMatrix[v2][v1] = 1;public void removeEdge(int v1, int v2) {adjMatrix[v1][v2] = INFINITY;adjMatrix[v2][v1] = INFINITY;// 省略其他方法…4.3 邻接表表示法实现邻接表的初始化、添加边、删除边等操作。
数据结构实验- 图
实验7 图1 实验要求编写图输入输出的重载操作,深度优先遍函数,广度优先遍历函数,取顶点的第一个邻接顶点函数,取顶点的邻接顶点的下一个邻接顶点函数,顶点的插入函数,边的插入函数,顶点的删除函数,边的删除函数。
2 简单的需求分析1,该程序的描述是:建立一个循环队列类,一个用邻接矩阵表示的图类,最后在主函数中调用图的输入重载操作建立一个图的对象,并且分别调用深度优先遍历函数,广度优先遍历函数,取顶点的第一个邻接顶点函数,取顶点的邻接顶点的下一个邻接顶点函数,顶点的插入函数,边的插入函数,顶点的删除函数,边的删除函数,以及图的输出重载操作,输出各自对应的结果。
2,程序运行后,首先要求用图的邻接矩阵表示建立图,即逐步输入图的顶点数,图的边数,图的顶点信息,图的端点信息,之后会出现所建立的图的信息,并出现一个界面,要求用户选择自己所要做的操作。
然后程序会输出各个操作所对应的内容:选择1,程序输出"请输入要从哪个顶点开始深度优先遍历:",用户输入顶点后,程序会输出图的深度优先遍历,之后继续提示用户选择上面的选项(1~9)。
选择2,程序输出"请输入要从哪个顶点开始广度优先遍历:",用户输入顶点后,程序会输出图的广度优先遍历,之后继续提示用户选择上面的选项(1~9)。
选择3,程序输出"输入所要操作的顶点:",用户输入顶点后,程序会输出该顶点的第一个邻接顶点,之后继续提示用户选择上面的选项(1~9)。
选择4,程序输出"输入所要操作的顶点:",用户输入顶点后,程序会输出该顶点的邻接顶点的下一个邻接顶点,之后继续提示用户选择上面的选项(1~9)。
选择5,程序输出"输入所要操作的顶点:",用户输入顶点后,程序会输出顶的插入后图的情况,之后继续提示用户选择上面的选项(1~9)。
选择6,程序输出"输入所要操作的边:",用户输入边的两个顶点已经权值后,程序会输出插入边后图的情况,之后继续提示用户选择上面的选项(1~9)。
数据结构实验报告图的遍历
数据结构实验报告图的遍历数据结构实验报告:图的遍历引言在计算机科学中,图是一种重要的数据结构,它由节点和边组成,用于表示不同实体之间的关系。
图的遍历是一种重要的操作,它可以帮助我们了解图中节点之间的连接关系,以及找到特定节点的路径。
在本实验中,我们将讨论图的遍历算法,并通过实验验证其正确性和效率。
深度优先搜索(DFS)深度优先搜索是一种常用的图遍历算法,它通过递归或栈的方式来遍历图中的节点。
在实验中,我们实现了深度优先搜索算法,并对其进行了测试。
实验结果表明,深度优先搜索算法能够正确地遍历图中的所有节点,并找到指定节点的路径。
此外,我们还对算法的时间复杂度进行了分析,验证了其在不同规模图上的性能表现。
广度优先搜索(BFS)广度优先搜索是另一种常用的图遍历算法,它通过队列的方式来遍历图中的节点。
在实验中,我们也实现了广度优先搜索算法,并对其进行了测试。
实验结果显示,广度优先搜索算法同样能够正确地遍历图中的所有节点,并找到指定节点的路径。
我们还对算法的时间复杂度进行了分析,发现其在不同规模图上的性能表现与深度优先搜索算法相近。
实验结论通过本次实验,我们深入了解了图的遍历算法,并验证了其在不同规模图上的正确性和效率。
我们发现深度优先搜索和广度优先搜索算法都能够很好地应用于图的遍历操作,且在不同情况下都有良好的性能表现。
这些算法的实现和测试为我们进一步深入研究图的相关问题提供了重要的基础。
总结图的遍历是图算法中的重要操作,它为我们提供了了解图结构和节点之间关系的重要手段。
本次实验中,我们实现并测试了深度优先搜索和广度优先搜索算法,验证了它们的正确性和效率。
我们相信这些算法的研究和应用将为我们在图相关问题的研究中提供重要的帮助。
数据结构实验十一:图实验
return al; //返回该邻接表
}
void print(algraph *alg){ //输出邻接表
int i;
arcnode *p; //定义一个邻接表结点型指针变量p
printf("该图的邻接表输出为:\n");
for(i=1;i<=alg->vexnum;i++){ //当在结点个数范围内时
2,结果的输出形式:输出的是两结点间是否存在路径的情况。
3,测试数据:输入的图的结点个数为:4
输入的图的边得个数为:3
边的信息为:1 2,2 3,3 1
三,概要设计
(1)为了实现上述程序的功能,需要:
A,用邻接表的方式构建图
B,深度优先遍历该图的结点
C,判断任意两结点间是否存在路径
(2)本程序包含6个函数:
scanf("%d",&e); //输入边得数目
printf("请输入弧的信息:\n");
for(i=0;i<e;i++){
printf("请输入边得两个结点:");
scanf("%d%d",&j,&k); //输入边的两个结点
p=(arcnode *)malloc(sizeof(arcnode)); //申请新的结点
typedef struct arcnode{
int adjvex;
arcnode *nextarc;
}arcnode;
(2)邻接表中头结点的类型定义:
typedef struct{
数据结构实验报告--图
.数据结构实验报告图一、实验目的1、熟悉图的结构和相关算法。
二、实验内容及要求1、编写创建图的算法。
2、编写图的广度优先遍历、深度优先遍历、及求两点的简单路径和最短路径的算法。
三、算法描述1、图的邻接表存储表示:对图的每个顶点建立一个单链表,第i个单链表表示所有依附于第i个点的边(对于有向图表示以该顶点为尾的弧);链表的每个节点存储两个信息,该弧指向的顶点在图中的位置(adjvex)和指向下一条弧的指针(nextarc)。
每个连表的头结点存储顶点的数据:顶点信息(data)和指向依附于它的弧的链表域。
存储表示如下:typedef struct ArcNode {int adjvex; // 该弧所指向的顶点的位置struct ArcNode *nextarc;// 指向下一条弧的指针// InfoType *info; // 该弧相关信息的指针} ArcNode;typedef struct VNode {char data; // 顶点信息int data2;int sngle;ArcNode *firstarc;// 指向第一条依附该顶点的弧} VNode, AdjList[MAX_NUM];typedef struct {AdjList vertices;int vexnum, arcnum;int kind; // 图的种类标志} ALGraph;2、深度优先搜索:假设初始态是图中所有定点未被访问,从图中的某个顶点v开始,访问此顶点,然后依次从v的未访问的邻接点出发深度优先遍历,直至途中所有和v有相同路径的点都被访问到;若图中仍有点未被访问,则从图中另选一个未被访问的点作为起点重复上述过程,直到图中所有点都被访问到。
为了便于区分途中定点是否被访问过,需要附设一个访问标致数组visited [0..n-1],将其初值均设为false,一旦某个顶点被访问,将对应的访问标志赋值为true。
2、广度优先搜索:假设初始态是图中所有顶点未被访问,从图中的某个顶点v开始依次访问v的各个未被访问的邻接点,然后分别从这些邻接点出发以此访问他们的邻接点,并使“先被访问的邻接顶点”先于“后被访问的邻接顶点”被访问,直至图中所有已被访问过的顶点的邻接顶点都被访问。
数据结构图实验
V0 to V3 25
V0 to V445
V0 to V51000
(“1000”means no path.)
3.Steps and restrict conditions:
Step 1.ImplementDepth-First SearchAlgorithm;
Step2.ImplementQueueADTrepresentedbycircularqueue,which hassevenbasic operations:CreateQueue,IsEmpty,DisposeQueue,MakeEmpty,EnQueue,Front,DeQueue.The element type is pointer of node;
0150// indicateanedgefrom V0 to V1.
0210
0 4 45
1 2 15
1 4 10
2 0 20
2 3 15
3 1 20
3 4 35
4 3 30
5 3 3
Figure 2
Output:
0:1 2 4
1:2 4
2:0 3
3:1 4
4:3
5:3
Thesequence of vertex names getting fromDepth-First Search(from ‘V1’):
(3).printthesequence of vertex names getting fromBreadth-First Search.
For example(See Figure 1):
Input:
6 11// indicate the graph includingsix vertexes and eleven edges.
数据结构--图实验
XXXX学院计算机工程系
《数据结构》·实验报告
实验名称实验8、图实验实验时间
学生姓名班级学号
指导教师批阅教师成绩
实验目的:
1)掌握图的逻辑结构;
2)掌握图的邻接矩阵储存结构;
3)验证图邻接矩阵储存及其遍历操作的实现。
实验设备:
联网的PC机一台,安装有Windows操作系统
实验内容:
1)建立无向图的邻接矩阵储存;
2)对建立的无向图,进行深度优先遍历;
3)对建立的无向图,进行广度优先遍历。
实验步骤及实验结果记录:
1.在VC++编程环境下新建一个工程“邻接矩阵验证实验”,在该工程中新建一个头
文件Mgraph.h,该头文件包括无向图类Mgraph的定义
2.在工程“邻接矩阵验证实验”中新建一个源文件Mgraph.cpp,该文件包括类Mgraph 中成员函数的定义
在工程“邻接矩阵验证实验”中新建一个源程序文件MGraph_Mian.cpp,该文件包括主函数
实验总结:在本次的实验中我学到了图中的邻接矩阵是怎样实现的,但是还是表现出了自己的不足之处,我还是有很多的地方是不会的,在以后的学习中,我需要加倍的努力才行。
数据结构图实验报告
数据结构图实验报告一、实验目的本次实验的主要目的是深入理解和掌握数据结构图的基本概念、原理和操作方法,通过实际编程和操作,提高对数据结构的应用能力和解决问题的能力。
二、实验环境本次实验使用的编程语言为C++,开发环境为Visual Studio 2019。
三、实验内容(一)线性表1、顺序表实现顺序表的创建、插入、删除、查找等基本操作。
分析顺序表在不同操作下的时间复杂度。
2、链表实现单链表、双向链表的创建、插入、删除、查找等基本操作。
比较单链表和双向链表在操作上的优缺点。
(二)栈和队列1、栈实现顺序栈和链式栈。
用栈解决表达式求值问题。
2、队列实现顺序队列和链式队列。
用队列模拟银行排队问题。
(三)树1、二叉树实现二叉树的创建、遍历(前序、中序、后序)。
计算二叉树的深度和节点数。
2、二叉搜索树实现二叉搜索树的插入、删除、查找操作。
分析二叉搜索树的性能。
(四)图1、图的存储实现邻接矩阵和邻接表两种图的存储方式。
比较两种存储方式的优缺点。
2、图的遍历实现深度优先遍历和广度优先遍历算法。
用图的遍历解决最短路径问题。
四、实验步骤(一)线性表1、顺序表定义一个数组来存储顺序表的元素,并使用一个变量记录当前表的长度。
插入操作时,需要判断插入位置是否合法,如果合法则将插入位置后的元素依次向后移动一位,然后将新元素插入指定位置。
删除操作时,先判断删除位置是否合法,合法则将删除位置后的元素依次向前移动一位,并更新表的长度。
查找操作通过遍历数组来实现。
分析不同操作的时间复杂度,插入和删除操作在最坏情况下为O(n),查找操作在平均情况下为 O(n/2)。
2、链表对于单链表,定义一个节点结构体,包含数据域和指向下一个节点的指针域。
通过操作指针来实现插入、删除和查找操作。
双向链表则在节点结构体中增加指向前一个节点的指针,使得操作更加灵活,但也增加了空间复杂度。
比较单链表和双向链表在插入、删除操作中指针的调整过程,得出双向链表在某些情况下更方便,但空间开销较大的结论。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
一,实验题目实验十一:图实验采用邻接表存储有向图,设计算法判断任意两个顶点间手否存在路径。
二,问题分析本程序要求采用邻接表存储有向图,设计算法判断任意两个顶点间手否存在路径,完成这些操作需要解决的关键问题是:用邻接表的形式存储有向图并输出该邻接表。
用一个函数实现判断任意两点间是否存在路径。
1,数据的输入形式和输入值的范围:输入的图的结点均为整型。
2,结果的输出形式:输出的是两结点间是否存在路径的情况。
3,测试数据:输入的图的结点个数为:4输入的图的边得个数为:3边的信息为:1 2,2 3,3 1三,概要设计(1)为了实现上述程序的功能,需要:A,用邻接表的方式构建图B,深度优先遍历该图的结点C,判断任意两结点间是否存在路径(2)本程序包含6个函数:a,主函数main()b,用邻接表建立图函数create_adjlistgraph()c,深度优先搜索遍历函数dfs()d,初始化遍历数组并判断有无通路函数dfs_trave()e,输出邻接表函数print()f,释放邻接表结点空间函数freealgraph()各函数间关系如右图所示:四,详细设计(1)邻接表中的结点类型定义:typedef struct arcnode{int adjvex;arcnode *nextarc;}arcnode;(2)邻接表中头结点的类型定义:typedef struct{char vexdata;arcnode *firstarc;}adjlist;(3)邻接表类型定义:typedef struct{adjlist vextices[max];int vexnum,arcnum;}algraph;(4)深度优先搜索遍历函数伪代码:int dfs(algraph *alg,int i,int n){arcnode *p; visited[i]=1; p=alg->vextices[i].firstarc;while(p!=NULL) { if(visited[p->adjvex]==0){if(p->adjvex==n) {flag=1; }dfs(alg,p->adjvex,n);if(flag==1) return 1; }p=p->nextarc; }return 0; }(5)初始化遍历数组并判断有无通路函数伪代码:void dfs_trave(algraph *alg,int x,int y){int i;for(i=0;i<=alg->vexnum;i++) visited[i]=0;dfs(alg,x,y); }五,源代码#include "stdio.h"#include "stdlib.h"#include "malloc.h"#define max 100typedef struct arcnode{ //定义邻接表中的结点类型int adjvex; //定点信息arcnode *nextarc; //指向下一个结点的指针nextarc}arcnode;typedef struct{ //定义邻接表中头结点的类型char vexdata; //头结点的序号arcnode *firstarc; //定义一个arcnode型指针指向头结点所对应的下一个结点}adjlist;typedef struct{ //定义邻接表类型adjlist vextices[max]; //定义表头结点数组int vexnum,arcnum; //定点个数和弧的个数}algraph;algraph *create_adjlistgraph(){ //建立邻接表函数int n,e,i,j,k;arcnode *p; //定义一个邻接表结点型指针变量palgraph *al; //定义邻接表表头结点指针alal=(algraph *)malloc(sizeof(algraph)); //为邻接表结点申请空间printf("请输入节点数:\n");scanf("%d",&n); //输入结点数for(i=0;i<=n;i++){al->vextices[i].vexdata=(char)i; //给头结点赋值al->vextices[i].firstarc=NULL; //初始化头结点}printf("请输入边数:\n");scanf("%d",&e); //输入边得数目printf("请输入弧的信息:\n");for(i=0;i<e;i++){printf("请输入边得两个结点:");scanf("%d%d",&j,&k); //输入边的两个结点p=(arcnode *)malloc(sizeof(arcnode)); //申请新的结点p->adjvex=k; //将k赋值给新申请的结点p->nextarc=al->vextices[j].firstarc; //使新结点指向该头结点所指向的下一个结点al->vextices[j].firstarc=p; //使头结点指向新结点}al->vexnum=n; //将顶点数n给al->vexnumal->arcnum=e; //将边数e给al->arcnumreturn al; //返回该邻接表}void print(algraph *alg){ //输出邻接表int i;arcnode *p; //定义一个邻接表结点型指针变量pprintf("该图的邻接表输出为:\n");for(i=1;i<=alg->vexnum;i++){ //当在结点个数范围内时printf("%d-",alg->vextices[i].vexdata); //输出i头结点的值p=alg->vextices[i].firstarc; //把i头结点所指的第一个结点给pwhile(p!=NULL){ //当p不为空时printf("%d-",p->adjvex); //输出给结点p=p->nextarc; //p指向下一个结点}printf("--\n");} }void freealgraph(algraph *alg){ //释放邻接表结点空间函数int i;arcnode *p,*q; //定义两个邻接表结点型指针变量p,qfor(i=0;i<=alg->vexnum;i++){ //当结点个数不超出范围时p=alg->vextices[i].firstarc; //p指向i头结点所对应的第一个结点while(p!=NULL){ //当p不为空时q=p->nextarc; //q指向p的下一个结点free(p); //释放pp=q; //将q赋给p}}}int visited[max]; //定义深度优先搜索遍历数组int flag=0; //设置标志,用来判断两点间是否为通路int dfs(algraph *alg,int i,int n){ //深度优先搜索遍历函数arcnode *p; //定义邻接表结点类型指针pvisited[i]=1; //将顶点i设置为已访问p=alg->vextices[i].firstarc; //使p指向i头结点所指的第一个结点while(p!=NULL) //当p不为空时{if(visited[p->adjvex]==0) //如果p结点未被访问{if(p->adjvex==n) //如果n=p结点的值{flag=1; //则将标志位设置为1}dfs(alg,p->adjvex,n); //递归调用深度优先搜索遍历函数if(flag==1) //如果已被访问return 1; //则返回1}p=p->nextarc; //p指向下一个结点}return 0;}void dfs_trave(algraph *alg,int x,int y){ //初始化遍历数组并判断有无通路函数int i;for(i=0;i<=alg->vexnum;i++)visited[i]=0;dfs(alg,x,y);}int main(){ //主函数int m,n;algraph *alg;alg=create_adjlistgraph(); //创建图print(alg); //输出该图printf("请输入任意要判定有无通路的两个顶点(输入(-1 -1)时退出):");scanf("%d%d",&m,&n);while(m!=-1&&n!=-1){dfs_trave(alg,m,n); //调用初始化遍历数组并判断有无通路函数if(flag==1)printf("顶点%d和%d之间存在路径\n",m,n);else{printf("顶点%d和%d之间不存在路径\n",m,n);flag=0;}printf("请输入任意要判定有无通路的两个顶点(输入(-1 -1)时退出):");scanf("%d%d",&m,&n);}freealgraph(alg); //释放邻接表结点空间return 0;}六,调试分析在函数调用时,弄错了实参和形参的含义,导致出现错误。
七,使用手册用户在使用时,根据界面提示,首先输入结点的个数,再输入边得个数,之后输入弧的信息,这时,图输入完成,输出该图的邻接表。
再根据提示,输入任意两个结点,判断他们之间是否有路径。
当输入的两结点为-1 -1时,输入结束。
八,测试结果。