数据结构实验报告无向图

合集下载

数据结构实验———图实验报告

数据结构实验———图实验报告

数据结构实验报告目的要求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 QElemType;typedef struct QNode{ //队的操作QElemType data;struct QNode *next;}QNode;*QueuePtr;typedef struct {QueuePtr front;QueuePtr rear;}LinkQueue;void InitQueueLinkQueue &Q{ //初始化队列Q.front =Q.rear =QueuePtrmallocsizeofQNode;ifQ.front exitOVERFLOW; //存储分配失败Q.front ->next =NULL;}int EnQueueLinkQueue &Q;QElemType e //插入元素e为Q的新的队尾元素{QueuePtr p;p=QueuePtrmallocsizeofQNode;ifp exitOVERFLOW;p->data=e;p->next=NULL;Q.rear->next=p;Q.rear =p;return OK;}int DeQueueLinkQueue &Q;QElemType &e //删除Q的队头元素;用e返回其值{ ifQ.front ==Q.rear return ERROR;QueuePtr p;p=Q.front ->next;e=p->data;Q.front->next=p->next ;ifQ.rear==p Q.rear =Q.front ;freep;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 visitedMAX_VERTEX_NUM; //全局变量——访问标志数组typedef struct ArcNode{int adjvex;struct ArcNode *nextarc;int weight; /*边的权*/}ArcNode; /*表结点*/typedef struct VNode{ int degree;indegree;/*顶点的度;入度*/V ertexType data;ArcNode *firstarc;}VNode/*头结点*/;AdjListMAX_VERTEX_NUM;typedef struct{ AdjList vertices;int vexnum;arcnum;/*顶点的实际数;边的实际数*/}ALGraph;//建立图的邻接表void creat_linkALGraph *G{ int i;j;ArcNode *s;printf"请依次输入顶点数、边数:";scanf"%d%d";&G->vexnum;&G->arcnum;for i=0;i<G->vexnum;i++{ G->verticesi.data='A'+i;G->verticesi.firstarc=NULL;}for i=0;i<G->vexnum;{ printf"请输入顶点的数组坐标若退出;请输入-1:";scanf"%d";&i;ifi==-1 break;printf"请输入顶点所指向下一个顶点的数组坐标:";scanf"%d";&j;s=ArcNode *mallocsizeofArcNode;s->adjvex=j;s->nextarc=G->verticesi.firstarc;G->verticesi.firstarc=s;}}// 输出邻接表void visitALGraph 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.verticesi.data;forp=G.verticesi.firstarc;p;p=p->nextarcprintf"%3d";p->adjvex;printf"\n";}}// 计算各顶点的度及入度void cacuALGraph *G{ArcNode *p;int i;for i=0;i<G->vexnum;i++{G->verticesi.degree=0;G->verticesi.indegree=0;}//度与初度初始化为零for i=0;i<G->vexnum;i++forp=G->verticesi.firstarc;p;p=p->nextarc{G->verticesi.degree++;G->verticesp->adjvex.degree++;G->verticesp->adjvex.indegree++;}}void print_degreeALGraph 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.verticesi.data;G.verticesi.degree;G.verticesi.indegree;printf"\n";}// 拓扑排序Status TopologiSortALGraph G{int i;count;top=0;stack50;ArcNode *p;cacu&G;print_degreeG;printf"\nTopologiSort is \n";fori=0;i<G.vexnum;i++ifG.verticesi.indegree stacktop++=i;count=0;whiletop=0{i=stack--top;if count==0 printf"%c";G.verticesi.data;else printf"-->%c";G.verticesi.data;count++;forp=G.verticesi.firstarc;p;p=p->nextarcif --G.verticesp->adjvex.indegreestacktop++=p->adjvex;}if count<G.vexnumreturnFALSE; else returnTRUE;}//在图G中寻找第v个顶点的第一个邻接顶点int FirstAdjVexALGraph G;int v{ifG.verticesv.firstarc return 0;else returnG.verticesv.firstarc->adjvex;}//在图G中寻找第v个顶点的相对于u的下一个邻接顶点int NextAdjVexALGraph G;int v;int u{ArcNode *p;p=G.verticesv.firstarc;whilep->adjvex=u p=p->nextarc; //在顶点v的弧链中找到顶点u ifp->nextarc==NULL return 0; //若已是最后一个顶点;返回0else returnp->nextarc->adjvex; //返回下一个邻接顶点的序号}//采用邻接表存储实现无向图的深度优先递归遍历void DFSALGraph G;int i{ int w;visitedi=True; //访问第i个顶点printf"%d->";i;forw=FirstAdjVexG;i;w;w=NextAdjVexG;i;wifvisitedw DFSG;w; //对尚未访问的邻接顶点w调用DFS}void DFSTraverseALGraph G{ int i;printf"DFSTraverse:";fori=0;i<G.vexnum;i++ visitedi=False; //访问标志数组初始化fori=0;i<G.vexnum;i++ifvisitedi DFSG;i; //对尚未访问的顶点调用DFS}//按广度优先非递归的遍历图G;使用辅助队列Q和访问标志数组visited void BFSTraverseALGraph G{int i;u;w;LinkQueue Q;printf"BFSTreverse:";fori=0;i<G.vexnum;i++ visitedi=False; //访问标志数组初始化InitQueueQ; //初始化队列fori=0;i<G.vexnum;i++ifvisitedi{visitedi=True; //访问顶点iprintf"%d->";i;EnQueueQ;i; //将序号i入队列whileQ.front ==Q.rear //若队列不空;继续{DeQueueQ;u; //将队头元素出队列并置为uforw=FirstAdjVexG;u;w;w=NextAdjV exG;u;wifvisitedw //对u的尚未访问的邻接顶点w进行访问并入队列{ visitedw=True;printf"%d->";w;EnQueueQ;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;switchselect{case 1:printf"\n创建一个有向图的邻接表:\n";creat_link&G;break;case 2:printf"\n输出该邻接表:\n";visitG;break;case 3:printf"\n输出该有向图的度和入度:\n";cacu&G;print_degreeG;break;case 4:printf"\n输出该有向图拓扑排序序列:\n";ifTopologiSortGprintf"Toposort is not success";break;case 5:printf"\n创建一个无向图的邻接表: \n";creat_link&G;break;case 6:printf"\n深度优先递归遍历该无向图: \n";DFSTraverseG;break;case 7:printf"\n广度优先遍历该无向图:\n";BFSTraverseG;break;case 0:break;default:printf"输入选项错误重新输入\n";}}whileselect;}运行结果截图:1.主菜单界面:2.创建一个有向图的领接表3.输出该邻接表4. 在有向图的邻接表的基础上计算各顶点的度;并输出..5. 输出它的拓扑排序序列6. 输出所建无向图的邻接表7. 深度优先递归遍历该无向图8. 广度优先遍历该无向图说明:本实验用的有向图是课本182页图7.28;无向图为课本168页图a实验总结这次的图的操作实验;与树的操作类似;但又比树复杂;包含更多的存储结构和遍历方法的操作;而且图的遍历需要沿着弧进行;以便输出弧上的信息..本实验中图的遍历采用邻接表的存储结构;在输入图的信息时;首先要画出图的邻接表信息..图有两种遍历的形式;一种为深度优先搜索;另一种为广度优先搜索..由于能力有限;没能实现图的深度非递归优先搜索;而是实现了图的深度递归优先搜索..本实验基本完成了图的操作;也学到了很多关于图的知识和算法..。

数据结构实验四报告

数据结构实验四报告

实验日期:_______________ 实验指导老师:
实验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、在邻接多重表中,所有依附于同一顶点的边串联在同一链表中。

算法与数据结构课设(有向图,无向图,有向网,无向网)

算法与数据结构课设(有向图,无向图,有向网,无向网)

算法与数据结构课程设计报告系(院):计算机科学学院专业班级:教技1001姓名:李##学号: ******### 指导教师:***设计时间:2012.6.16 - 2012.6.24设计地点:4号楼2号机房目录一、设计方案 (1)二、实现过程以及代码 (2)三、测试 (20)四、结论和分析 (23)五、难点和收获 (23)一、 设计方案1.程序设计基本过程:拿到课程设计任务书,按照要求,需要设计有向图、有向网、无向图 、无向网四种图,以及邻接矩阵、邻接表两种数据存储结构,三层以上的显示菜单。

图的操作中又包含了有关线性表、栈和队列的基本操作。

由于显示菜单已给出,剩下的任务就是把函数写入其中。

2.程序流程图:预定义 定义结构体 定义变量 各种函数3.程序设计的原理:图的操作都是以两种存储结构为基础的:邻接矩阵存储结构和邻接表存储结构,如有向图,有向网,无向图,无向网的创建,其他的操作都是在四种图创建后才开始进行的。

所以,首先必须理解两种存储结构的定义。

图的邻接矩阵存储结构即图的数组表示法。

用两个数组分别存储数据元素(如顶点)的信息和数据元素之间的关系(如边或弧)的信息。

用邻接矩阵存储结构的图具有以下几点特征:(一):顶点数:vexnum ,边(弧)数:arcnum ,图的种类:kind ;(二):邻接矩阵:arcs(1顶点关系类型:adj 2相关信息:*info);(三):顶点向量(顶点名):vexs[];其优点是以二维数组表示有n 个顶点的图时,需存放n 个顶点的信息和n*n 条弧的信息存储量。

借助邻接矩阵容易判定任意两个顶点之间是否有边或弧相连,并容易求出各个顶点的度。

缺点是时间复杂度是O (n*n ),例如,构造一个具有n 个顶点和e 条边的无向网的时间复杂度为O (n*n+e*n )。

图的邻接表存储结构是图的一种链式存储结构。

对图中的每个顶点建立一个单链表,每个结点由三个域组成,邻接点域adjvex (弧尾在邻接表链表中的位序),链域nextarc (下一条弧),数据域info(权值)。

数据结构图的实验报告

数据结构图的实验报告

数据结构图的实验报告数据结构图的实验报告引言:数据结构图是计算机科学中重要的概念之一。

它是一种用图形表示数据元素之间关系的数据结构,广泛应用于算法设计、程序开发和系统优化等领域。

本实验报告旨在介绍数据结构图的基本原理、实验过程和结果分析。

一、实验目的本次实验的主要目的是掌握数据结构图的基本概念和操作方法,以及通过实验验证其在解决实际问题中的有效性。

具体而言,我们将通过构建一个社交网络关系图,实现对用户关系的管理和分析。

二、实验方法1. 确定数据结构在本次实验中,我们选择了无向图作为数据结构图的基础。

无向图由顶点集和边集组成,每条边连接两个顶点,且没有方向性。

2. 数据输入为了模拟真实的社交网络,我们首先需要输入一组用户的基本信息,如姓名、年龄、性别等。

然后,根据用户之间的关系建立边,表示用户之间的交流和联系。

3. 数据操作基于构建好的数据结构图,我们可以进行多种操作,如添加用户、删除用户、查询用户关系等。

这些操作将通过图的遍历、搜索和排序等算法实现。

三、实验过程1. 数据输入我们首先创建一个空的无向图,并通过用户输入的方式逐步添加用户和用户关系。

例如,我们可以输入用户A和用户B的姓名、年龄和性别,并建立一条边连接这两个用户。

2. 数据操作在构建好数据结构图后,我们可以进行多种操作。

例如,我们可以通过深度优先搜索算法遍历整个图,查找与某个用户具有特定关系的用户。

我们也可以通过广度优先搜索算法计算某个用户的社交网络影响力,即与该用户直接或间接相连的其他用户数量。

3. 结果分析通过实验,我们可以观察到数据结构图在管理和分析用户关系方面的优势。

它能够快速地找到用户之间的关系,帮助我们了解用户的社交网络结构和影响力。

同时,数据结构图也为我们提供了一种可视化的方式来展示用户之间的关系,使得分析更加直观和易于理解。

四、实验结果通过实验,我们成功构建了一个社交网络关系图,并实现了多种数据操作。

我们可以根据用户的姓名、年龄和性别等信息进行查询,也可以根据用户之间的关系进行遍历和排序。

数据结构试验报告-图的基本操作

数据结构试验报告-图的基本操作

中原工学院《数据结构》实验报告学院:计算机学院专业:计算机科学与技术班级:计科112姓名:康岩岩学号:201100814220 指导老师:高艳霞2012-11-22实验五图的基本操作一、实验目的1、使学生可以巩固所学的有关图的基本知识。

2、熟练掌握图的存储结构。

3、熟练掌握图的两种遍历算法。

二、实验内容[问题描述]对给定图,实现图的深度优先遍历和广度优先遍历。

[基本要求]以邻接表为存储结构,实现连通无向图的深度优先和广度优先遍历。

以用户指定的结点为起点,分别输出每种遍历下的结点访问序列。

【测试数据】由学生依据软件工程的测试技术自己确定。

三、实验前的准备工作1、掌握图的相关概念。

2、掌握图的逻辑结构和存储结构。

3、掌握图的两种遍历算法的实现。

四、实验报告要求1、实验报告要按照实验报告格式规范书写。

2、实验上要写出多批测试数据的运行结果。

3、结合运行结果,对程序进行分析。

【设计思路】【代码整理】#include "stdafx.h"#include <iostream>#include <malloc.h>using namespace std;typedef int Status;#define OK 1#define ERROR 0#define OVERFLOW -1#define MAX_SIZE 20typedef enum{DG,DN,UDG,UDN}Kind;typedef struct ArcNode{int adjvex; //顶点位置struct ArcNode *nextarc; //下一条弧int *info; //弧信息};typedef struct{char info[10]; //顶点信息ArcNode *fistarc; //指向第一条弧}VNode,AdjList[MAX_SIZE];typedef struct{AdjList vertices;int vexnum,arcnum; //顶点数,弧数int kind; //图的种类,此为无向图}ALGraph;//这是队列的节点,仅用于广度优先搜索typedef struct Node{int num;struct Node* next;};//队列的头和尾typedef struct{Node * front;Node *rear;}PreBit;int LocateV ex(ALGraph G,char info[]);//定位顶点的位置Status addArcNode(ALGraph &G,int adjvex); //图中加入弧Status CreatGraph(ALGraph&G);//创建图的邻接表Status DFSTraverse(ALGraph G);//深度优先搜索Status BFSTraverse(ALGraph G);//广度优先搜索Status DFS(ALGraph G,int v);//深度优先搜索中的数据读取函数,用于递归bool visited[MAX_SIZE]; // 访问标志数组//初始化队列Status init_q(PreBit&P_B){P_B.front=P_B.rear=(Node*)malloc(sizeof(Node));if(!P_B.front){exit(OVERFLOW);}P_B.front->next=NULL;}//将数据入队Status en_q(PreBit & P_B,int num){Node *p=(Node*)malloc(sizeof(Node));if(!p){exit(OVERFLOW);}p->num=num;p->next=NULL;P_B.rear->next=p;P_B.rear=p;return OK;}//出队Status de_q(PreBit & P_B){if(P_B.front==P_B.rear){return ERROR;}Node* p=P_B.front->next;P_B.front->next=p->next;if(P_B.rear==p){P_B.rear=P_B.front;}free(p);return OK;}Status CreatGraph(ALGraph&G){cout<<"请输入顶点数目和弧数目"<<endl;cin>>G.vexnum>>G.arcnum;//依次输入顶点信息for(int i=0;i<G.vexnum;i++){cout<<"请输入顶点名称"<<endl;cin>>G.vertices[i].info;G.vertices[i].fistarc=NULL;}//依次输入弧信息for(int k=1;k<=G.arcnum;k++){char v1[10],v2[10]; //用于表示顶点名称的字符数组int i,j; //表示两个顶点的位置BACK: //返回点cout<<"请输入第"<<k<<"条弧的两个顶点"<<endl;cin>>v1>>v2;i=LocateV ex(G,v1); //得到顶点v1的位置j=LocateV ex(G,v2); //得到顶点v2的位置if(i==-1||j==-1){ //头信息不存在则返回重输cout<<"不存在该节点!"<<endl;goto BACK; //跳到BACK 返回点}addArcNode(G,i); //将弧的顶点信息插入表中addArcNode(G,j);}return OK;}//倒序插入弧的顶点信息Status addArcNode(ALGraph &G,int adjvex){ArcNode *p; //弧节点指针p=(ArcNode*)malloc(sizeof(ArcNode));p->adjvex=adjvex;p->nextarc=G.vertices[adjvex].fistarc;//指向头结点的第一条弧G.vertices[adjvex].fistarc=p; //头结点的第一条弧指向p,即将p作为头结点的第一条弧return OK;}//定位顶点的位置int LocateV ex(ALGraph G,char info[]){for(int i=0;i<G.vexnum;i++){if(strcmp(G.vertices[i].info,info)==0){ //头结点名称与传入的信息相等,证明该头节点存在return i; //此时返回位置}}return -1;}//深度优先搜索Status DFSTraverse(ALGraph G){for(int v=0;v<G.vexnum;v++){visited[v]=false;}char v1[10];int i;BACK:cout<<"请输入首先访问的顶点"<<endl;cin>>v1;i=LocateV ex(G,v1);if(i==-1){cout<<"不存在该节点!"<<endl;goto BACK;}DFS(G,i);return OK;}//深度优先搜索递归访问图Status DFS(ALGraph G,int v){visited[v]=true;cout<<G.vertices[v].info<<" ";//输出信息ArcNode *p;p=G.vertices[v].fistarc; //向头节点第一条while(p) //当弧存在{if(!visited[p->adjvex]){DFS(G,p->adjvex); //递归读取}p=p->nextarc;}return OK;}//广度优先搜索Status BFSTraverse(ALGraph G){for(int v=0;v<G.vexnum;v++){visited[v]=false;}char v1[10];int v;BACK:cout<<"请输入首先访问的顶点"<<endl;cin>>v1;v=LocateV ex(G,v1);if(v==-1){cout<<"不存在该节点!"<<endl;goto BACK;}PreBit P_B;init_q(P_B);ArcNode *p;visited[v]=true;cout<<G.vertices[v].info<<" ";//输出信息en_q(P_B,v); //将头位置v入队while(P_B.front!=P_B.rear){//当队列不为空时,对其进行访问int w=P_B.front->next->num;//读出顶点位置de_q(P_B);//顶点已经访问过,将其出队列p=G.vertices[w].fistarc;//得到与顶点相关的第一条弧while(p){if(!visited[p->adjvex]){en_q(P_B,p->adjvex);//将弧入队,但不读取,只是将其放在队尾}p=p->nextarc;}}return OK;}int _tmain(int argc, _TCHAR* argv[]){ALGraph G;CreatGraph(G);cout<<"深度优先搜索图:"<<endl;DFSTraverse(G);cout<<endl;cout<<"广度优先搜索图:"<<endl;BFSTraverse(G);cout<<endl;system("pause");return 0;}。

数据结构实验报告-图的遍历

数据结构实验报告-图的遍历

数据结构实验报告实验:图的遍历一、实验目的: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.通过图的相关算法实现,掌握其算法思想。

二、实验内容及要求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.本程序可以实现无向图的邻接链表存储,并以深度、广度优先非递归遍历输出。

4.程序执行的命令包括:(1)建立一个无向图的邻接链表存储(2)以深度优先遍历输出(3)以广度优先遍历输出(4)结束5.测试数据:顶点数和边数:6,5顶点信息:a b c d e f边的顶点对应序号:0,10,20,32,43,4深度优先遍历输出:a d e c bf广度优先遍历输出:a d cb ef二概要设计为了实现上述操作,应以邻接链表为存储结构。

1.基本操作:void createalgraph(algraph &g)创建无向图的邻接链表存储void dfstraverseal(algraph &g,int v)以深度优先遍历输出void bfstraverseal(algraph &g,int v) 以广度优先遍历输出2.本程序包含四个模块:(1)主程序模块(2)无向图的邻接链表存储模块(3)深度优先遍历输出模块(4)广度优先遍历输出模块3.模块调用图:三详细设计1.元素类型,结点类型和指针类型:typedef struct node{int adjvex;struct node *next;}edgenode;typedef struct vnode{char vertex;edgenode *firstedge;}vertxnode;typedef vertxnode Adjlist[maxvernum]; typedef struct{Adjlist adjlist;int n,e;}algraph;edgenode *s;edgenode *stack[maxvernum],*p;2.每个模块的分析:(1)主程序模块int main(){int v=0;algraph g;createalgraph(g);printf("以深度优先遍历输出\n");dfstraverseal(g,v);printf("以广度优先遍历输出\n");bfstraverseal(g,v);getchar();getchar();return 0;}(2)无向图的邻接链表存储模块void createalgraph(algraph &g){int i,j,k;edgenode *s;printf("请输入顶点数和边数(输入格式为:顶点数,边数):\n");scanf("%d,%d",&(g.n),&(g.e)); /*读入顶点数和边数*/getchar();printf("请输入顶点信息(输入格式为:(顶点号(CR))):\n");for(i=0;i<g.n;i++) /*建立有n个顶点的顶点表*/{scanf("%c",&(g.adjlist[i].vertex)); /*读入顶点信息*/getchar();g.adjlist[i].firstedge=NULL; /*顶点的边表头指针设为空*/}printf("请输入边的信息(输入格式为:i,j):\n");for(k=0;k<g.e;k++) /*建立边表*/{scanf("%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;s=(edgenode *)malloc(sizeof(edgenode)); /*生成新边表节点s*/s->adjvex=i; /*邻接点序号为i*/s->next=g.adjlist[j].firstedge; /*将新边表节点s插入到顶点vj的边表头部*/g.adjlist[j].firstedge=s;}}(3)深度优先遍历输出模块{int j=0;edgenode *stack[maxvernum],*p;int visited[maxvernum],top=-1,i;for(i=0;i<g.n;i++)visited[i]=0;while(j!=g.n){i=0;while(visited[i]==1){i++;}v=i;printf("%c ",g.adjlist[v].vertex); /*访问图的指定起始顶点v*/j++;p=g.adjlist[v].firstedge;visited[v]=1;while(top>=0||p!=NULL){while(p!=NULL)if(visited[p->adjvex]==1)p=p->next;else{printf("%c ",g.adjlist[p->adjvex].vertex); /*从v出发访问一个与v邻接的p所指的顶点*/j++;visited[p->adjvex]=1;top++;stack[top]=p; /*将p所指的顶点入栈*/p=g.adjlist[p->adjvex].firstedge; /*从p所指顶点出发*/}if(top>=0){p=stack[top]; /*退栈,回溯查找已被访问节点的未被访问过的邻接点*/top--;p=p->next;}}printf("\n");}}(4)广度优先遍历输出模块{int i,front=-1,rear=-1,j=0;edgenode *p;for(i=0;i<g.n;i++)visited[i]=0;while(j!=g.n){i=0;while(visited[i]==1){i++;}v=i;visited[v]=1;printf("%c ",g.adjlist[v].vertex);j++;rear++;queue[rear]=v; /*初始顶点入队*/while(front!=rear) /*队列不为空*/{front=front+1;v=queue[front]; /*按访问次序出队列*/p=g.adjlist[v].firstedge; /*找v的邻接顶点*/while(p!=NULL){if(visited[p->adjvex]==0){visited[p->adjvex]=1;printf("%c ",g.adjlist[p->adjvex].vertex);j++;rear=rear+1;queue[rear]=p->adjvex;}p=p->next;}}printf("\n");}}3.函数调用图:4.完整的程序:(见源文件)。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

《数据结构》实验报告◎实验题目: 无向图的建立与遍历◎实验目的:掌握无向图的邻接链表存储,熟悉无向图的广度与深度优先遍历。

◎实验内容:对一个无向图以邻接链表存储,分别以深度、广度优先非递归遍历输出。

一、需求分析1.本演示程序中,输入的形式为无向图的邻接链表形式,首先输入该无向图的顶点数和边数,接着输入顶点信息,再输入每个边的顶点对应序号。

2.该无向图以深度、广度优先遍历输出。

3.本程序可以实现无向图的邻接链表存储,并以深度、广度优先非递归遍历输出。

4.程序执行的命令包括:(1)建立一个无向图的邻接链表存储(2)以深度优先遍历输出(3)以广度优先遍历输出(4)结束5.测试数据:顶点数和边数:6,5顶点信息:a b c d e f边的顶点对应序号:0,10,20,32,43,4深度优先遍历输出:a d e c bf广度优先遍历输出:a d cb ef二概要设计为了实现上述操作,应以邻接链表为存储结构。

1.基本操作:void createalgraph(algraph &g)创建无向图的邻接链表存储void dfstraverseal(algraph &g,int v)以深度优先遍历输出void bfstraverseal(algraph &g,int v) 以广度优先遍历输出2.本程序包含四个模块:(1)主程序模块(2)无向图的邻接链表存储模块(3)深度优先遍历输出模块(4)广度优先遍历输出模块3.模块调用图:三详细设计1.元素类型,结点类型和指针类型:typedef struct node{int adjvex;struct node *next;}edgenode;typedef struct vnode{char vertex;edgenode *firstedge;}vertxnode;typedef vertxnode Adjlist[maxvernum]; typedef struct{Adjlist adjlist;int n,e;}algraph;edgenode *s;edgenode *stack[maxvernum],*p;2.每个模块的分析:(1)主程序模块int main(){int v=0;algraph g;createalgraph(g);printf("以深度优先遍历输出\n");dfstraverseal(g,v);printf("以广度优先遍历输出\n");bfstraverseal(g,v);getchar();getchar();return 0;}(2)无向图的邻接链表存储模块void createalgraph(algraph &g){int i,j,k;edgenode *s;printf("请输入顶点数和边数(输入格式为:顶点数,边数):\n");scanf("%d,%d",&(g.n),&(g.e)); /*读入顶点数和边数*/getchar();printf("请输入顶点信息(输入格式为:(顶点号(CR))):\n");for(i=0;i<g.n;i++) /*建立有n个顶点的顶点表*/{scanf("%c",&(g.adjlist[i].vertex)); /*读入顶点信息*/getchar();g.adjlist[i].firstedge=NULL; /*顶点的边表头指针设为空*/}printf("请输入边的信息(输入格式为:i,j):\n");for(k=0;k<g.e;k++) /*建立边表*/{scanf("%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;s=(edgenode *)malloc(sizeof(edgenode)); /*生成新边表节点s*/s->adjvex=i; /*邻接点序号为i*/s->next=g.adjlist[j].firstedge; /*将新边表节点s插入到顶点vj的边表头部*/g.adjlist[j].firstedge=s;}}(3)深度优先遍历输出模块{int j=0;edgenode *stack[maxvernum],*p;int visited[maxvernum],top=-1,i;for(i=0;i<g.n;i++)visited[i]=0;while(j!=g.n){i=0;while(visited[i]==1){i++;}v=i;printf("%c ",g.adjlist[v].vertex); /*访问图的指定起始顶点v*/j++;p=g.adjlist[v].firstedge;visited[v]=1;while(top>=0||p!=NULL){while(p!=NULL)if(visited[p->adjvex]==1)p=p->next;else{printf("%c ",g.adjlist[p->adjvex].vertex); /*从v出发访问一个与v邻接的p所指的顶点*/j++;visited[p->adjvex]=1;top++;stack[top]=p; /*将p所指的顶点入栈*/p=g.adjlist[p->adjvex].firstedge; /*从p所指顶点出发*/}if(top>=0){p=stack[top]; /*退栈,回溯查找已被访问节点的未被访问过的邻接点*/top--;p=p->next;}}printf("\n");}}(4)广度优先遍历输出模块{int i,front=-1,rear=-1,j=0;edgenode *p;for(i=0;i<g.n;i++)visited[i]=0;while(j!=g.n){i=0;while(visited[i]==1){i++;}v=i;visited[v]=1;printf("%c ",g.adjlist[v].vertex);j++;rear++;queue[rear]=v; /*初始顶点入队*/while(front!=rear) /*队列不为空*/{front=front+1;v=queue[front]; /*按访问次序出队列*/p=g.adjlist[v].firstedge; /*找v的邻接顶点*/while(p!=NULL){if(visited[p->adjvex]==0){visited[p->adjvex]=1;printf("%c ",g.adjlist[p->adjvex].vertex);j++;rear=rear+1;queue[rear]=p->adjvex;}p=p->next;}}printf("\n");}}3.函数调用图:4.完整的程序:(见源文件)。

四使用说明、测试分析及结果1.程序使用说明(1)本程序的运行环境为VC6.0。

(2)进入演示程序后即显示提示信息:请输入顶点数和边数(输入格式为:顶点数,边数): 请输入顶点信息(输入格式为:(顶点号(CR))):请输入边的信息(输入格式为:i,j):2.测试数据:顶点数和边数:6,5顶点信息:a b c d e f 边的顶点对应序号:0,10,20,32,43,4深度优先遍历输出:a d e c bf广度优先遍历输出:a d cb ef3.运行界面:五、实验总结本次程序由于书上有相关程序作为参考,所以编写起来比较顺手,通过本次编程,对于无向图的邻接链表存储有了一定的基础,同时还熟练掌握了无向图的深度、广度优先遍历输出,中间由于要存储无向不连通图,出了点小问题,在自己的努力下和同学的帮助下,完成了无向不连通图的存储与遍历输出。

通过本次试验对于无向图有了更深的了解,可以很好地掌握它的建立与遍历输出。

教师评语:#include<stdio.h>#include<malloc.h>#define maxvernum 100typedef struct node{int adjvex;struct node *next;}edgenode;typedef struct vnode{char vertex;edgenode *firstedge;}vertxnode;typedef vertxnode Adjlist[maxvernum];typedef struct{Adjlist adjlist;int n,e;}algraph;int visited[maxvernum];int queue[maxvernum];//创建无向图void createalgraph(algraph &g){int i,j,k;edgenode *s;printf("请输入顶点数和边数(输入格式为:顶点数,边数):\n");scanf("%d,%d",&(g.n),&(g.e)); /*读入顶点数和边数*/getchar();printf("请输入顶点信息(输入格式为:(顶点号(CR))):\n");for(i=0;i<g.n;i++) /*建立有n个顶点的顶点表*/{scanf("%c",&(g.adjlist[i].vertex)); /*读入顶点信息*/getchar();g.adjlist[i].firstedge=NULL; /*顶点的边表头指针设为空*/}printf("请输入边的信息(输入格式为:i,j):\n");for(k=0;k<g.e;k++) /*建立边表*/{scanf("%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;s=(edgenode *)malloc(sizeof(edgenode)); /*生成新边表节点s*/s->adjvex=i; /*邻接点序号为i*/s->next=g.adjlist[j].firstedge; /*将新边表节点s插入到顶点vj的边表头部*/g.adjlist[j].firstedge=s;}}//深度优先void dfstraverseal(algraph &g,int v){int j=0;edgenode *stack[maxvernum],*p;int visited[maxvernum],top=-1,i;for(i=0;i<g.n;i++)visited[i]=0;{i=0;while(visited[i]==1){i++;}v=i;printf("%c ",g.adjlist[v].vertex); /*访问图的指定起始顶点v*/j++;p=g.adjlist[v].firstedge;visited[v]=1;while(top>=0||p!=NULL){while(p!=NULL)if(visited[p->adjvex]==1)p=p->next;else{printf("%c ",g.adjlist[p->adjvex].vertex); /*从v出发访问一个与v邻接的p所指的顶点*/j++;visited[p->adjvex]=1;top++;stack[top]=p; /*将p所指的顶点入栈*/p=g.adjlist[p->adjvex].firstedge; /*从p所指顶点出发*/}if(top>=0){p=stack[top]; /*退栈,回溯查找已被访问节点的未被访问过的邻接点*/top--;p=p->next;}}printf("\n");}}//广度优先void bfstraverseal(algraph &g,int v){int i,front=-1,rear=-1,j=0;edgenode *p;for(i=0;i<g.n;i++)visited[i]=0;{i=0;while(visited[i]==1){i++;}v=i;visited[v]=1;printf("%c ",g.adjlist[v].vertex);j++;rear++;queue[rear]=v; /*初始顶点入队*/while(front!=rear) /*队列不为空*/{front=front+1;v=queue[front]; /*按访问次序出队列*/p=g.adjlist[v].firstedge; /*找v的邻接顶点*/while(p!=NULL){if(visited[p->adjvex]==0){visited[p->adjvex]=1;printf("%c ",g.adjlist[p->adjvex].vertex);j++;rear=rear+1;queue[rear]=p->adjvex;}p=p->next;}}printf("\n");}}int main(){int v=0;algraph g;createalgraph(g);printf("以深度优先遍历输出\n");dfstraverseal(g,v);printf("以广度优先遍历输出\n");bfstraverseal(g,v);getchar();getchar();return 0; }。

相关文档
最新文档