数据结构实验报告--图

合集下载

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

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

数据结构实验报告目的要求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实验总结这次的图的操作实验;与树的操作类似;但又比树复杂;包含更多的存储结构和遍历方法的操作;而且图的遍历需要沿着弧进行;以便输出弧上的信息..本实验中图的遍历采用邻接表的存储结构;在输入图的信息时;首先要画出图的邻接表信息..图有两种遍历的形式;一种为深度优先搜索;另一种为广度优先搜索..由于能力有限;没能实现图的深度非递归优先搜索;而是实现了图的深度递归优先搜索..本实验基本完成了图的操作;也学到了很多关于图的知识和算法..。

数据结构实验报告图实验

数据结构实验报告图实验

图实验一,邻接矩阵的实现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. 确定数据结构在本次实验中,我们选择了无向图作为数据结构图的基础。

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

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、实验环境
本次实验使用编程语言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. 实验目的本实验的主要目的是掌握图的基本概念和相关操作,包括图的创建、遍历、搜索和最短路径算法等。

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

.数据结构实验报告图一、实验目的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的各个未被访问的邻接点,然后分别从这些邻接点出发以此访问他们的邻接点,并使“先被访问的邻接顶点”先于“后被访问的邻接顶点”被访问,直至图中所有已被访问过的顶点的邻接顶点都被访问。

若图中仍有未被访问的顶点,选择另一个未被访问的顶点开始,重复上述操作,直到图中所有顶点都被访问。

为了使“先被访问的邻接顶点”先于“后被访问的邻接顶点”被访问,在次算法中加入一个队列,queue暂时存储被访问的顶点。

3、搜索简单路径:利用深度优先搜索,以一个要搜索的起点v顶点为起始点,搜索到要找的终点s 结束。

为了方便记录路径,此算法中加入栈。

访问第v个顶点时将v入栈,以v 为顶点进行深度优先搜索,分别将其邻接点vi入栈,若找到s,将s入栈,若没有找到,将vi出栈;对vi+1深度优先搜索,直到找到s,或者图中所有顶点都被访问。

4、搜索最短路径:搜索最短路径时,要记录被访问的顶点的上一个顶点在图中的位置,所以添加一个上一个顶点的标识single;访问v时将其标识置为-1;搜索从v到s的最短路径,从v开始进行广度优先搜索,直到找到s,将s以及它的之前的顶点依次入栈,直到将v入栈,然后将栈内元素输出。

四、程序代码:#include<stdio.h>#include<stdlib.h>#include <conio.h>#define MAX_NUM 20bool visited[MAX_NUM];//访问标致数组bool found;int fomer=0;char v1,v2;int tfind;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;void DFS(ALGraph G,int v);typedef struct qnode //队列类型{int data;qnode *next;}qnode,*queueptr;typedef struct{queueptr front;queueptr rear;}linkqueue;typedef struct stack//用栈存储路径{char *base;char *top;int stacksize;int size;}Stack;Stack s;int initstack(Stack &s){s.base=(char*)malloc(40*sizeof(char));s.top=s.base;s.stacksize=40;s.size=0;return 1;}int push(Stack &s,char e){*s.top++=e;s.size++;return 1;}int pop(Stack &s,char &e){if(s.base==s.top)e=*--s.top;else {e=*--s.top;s.size--;}return 1;}void printstack(Stack s){while(s.base!=s.top){printf("%c ",*s.base);s.base++;}printf("\n");}void printstack2(Stack s){while(s.base!=s.top){printf("%c ",*--s.top);}printf("\n");}int intitqueue(linkqueue &q)//初始化队列{q.front=q.rear=(queueptr)malloc(sizeof(qnode));q.front->next=NULL;return 1;}int emptyqueue(linkqueue q)//判断对了是否为空{if (q.front==q.rear)return 1;return 0;}int enqueue(linkqueue &q,int e)//元素入队{queueptr p;p=(queueptr)malloc(sizeof(qnode));if(!p) exit(0);p->data=e; p->next=NULL;q.rear->next=p;q.rear=p;return 1;}int dequeue(linkqueue &q,int &e)//元素出队{queueptr p;if(q.front==q.rear) return 0;p=q.front->next;e=p->data;q.front->next=p->next;if(q.rear==p) q.rear=q.front;free(p);return 1;}int LocateVex(ALGraph &G,char v){int i;for(i=0;i<G.vexnum;i++)if(G.vertices[i].data==v)return i;return -1;}int FirstAdjVex(ALGraph G,int v){if(G.vertices[v].firstarc!=NULL)return G.vertices[v].firstarc->adjvex;return -1;}int NextAdjVex(ALGraph G,int v,int w){while (G.vertices[v].firstarc->nextarc!=NULL){if(G.vertices[v].firstarc->adjvex==w)return G.vertices[v].firstarc->nextarc->adjvex;else G.vertices[v].firstarc=G.vertices[v].firstarc->nextarc;}return -1;}void Create(ALGraph &G){int i,j,k;char v1,v2;ArcNode *p,*q,*h;q=NULL;h=NULL;printf("输入节点个数和弧的个数:\n");scanf("%d%d",&G.vexnum,&G.arcnum);for(i=0;i<G.vexnum;i++){fflush(stdin);printf("输入节点名称:\n");scanf("%c",&G.vertices[i].data);G.vertices[i].firstarc=NULL;G.vertices[i].data2=i;}for(k=0;k<G.arcnum;k++){printf("输入弧:a,b:\n");fflush(stdin);scanf("%c,%c",&v1,&v2);i=LocateVex(G,v1);j=LocateVex(G,v2);p=(ArcNode*)malloc(sizeof(ArcNode));p->adjvex=j;p->nextarc=NULL;if (G.vertices[i].firstarc==NULL)G.vertices[i].firstarc=p;else{q=G.vertices[i].firstarc;while(q->nextarc!=NULL)q=q->nextarc;q->nextarc=p;}}}void DFSTraverse(ALGraph G)//深度遍历{int v;for(v=0;v<G.vexnum;v++)if(!visited[v]) DFS(G,v);printf("\n");}void DFS(ALGraph G,int v)//深度遍历{int w;visited[v]=true;printf("%c ",G.vertices[v].data);for(w=FirstAdjVex(G,v);(w>=0)&&(tfind==0);w=NextAdjVex(G,v,w)) {if(!visited[w]) DFS(G,w);}}void DFSTree(ALGraph G)//广度遍历{int w,u,v;linkqueue q;intitqueue(q);for (v=0;v<G.vexnum;v++){if (!visited[v]){visited[v]=true;printf("%c ",G.vertices[v].data);enqueue(q,v);}while (!emptyqueue(q)){dequeue(q,u);for (w=FirstAdjVex(G,u);w>0;w=NextAdjVex(G,u,w))if (!visited[w]){visited[w]=true;printf("%c ",G.vertices[w].data);if(w>0)enqueue(q,w);}}}printf("\n");}void DFS2(ALGraph G,int v)//用深度遍历算法实现搜索简单路径{int w;char e;visited[v]=true;push(s,G.vertices[v].data);for(w=FirstAdjVex(G,v);(w>=0)&&(!found);w=NextAdjVex(G,v,w)) {if(G.vertices[w].data==v2){found=true;push(s,G.vertices[w].data);}else if(!visited[w]) DFS2(G,w);}if(!found) pop(s,e);}void Simplepath(ALGraph G)//搜索简单路径{printf("输入要搜索路径的两点:\n");fflush(stdin);scanf("%c",&v1);fflush(stdin);scanf("%c",&v2);DFS2(G,LocateVex(G,v1));if (!found){printf("can not found zhe path!\n");}else printstack(s);}void DFSTree2(ALGraph G,int v)//用广度优先求最短路径{int w,u;linkqueue q;intitqueue(q);if (!visited[v]){visited[v]=true;G.vertices[v].sngle=-1;enqueue(q,v);}while (!emptyqueue(q)){dequeue(q,u);for (w=FirstAdjVex(G,u);(w>0)&&(!found);w=NextAdjVex(G,u,w)) if (!visited[w]){visited[w]=true;G.vertices[w].sngle=u;if(w>0)enqueue(q,w);if(G.vertices[w].data==v2){found=true;while (G.vertices[w].sngle!=-1){push(s,G.vertices[w].data);w=G.vertices[w].sngle;}}}}printf("\n");}void shortcut(ALGraph G)//搜索最短路径{printf("输入要搜索路径的两点:\n");fflush(stdin);scanf("%c",&v1);fflush(stdin);scanf("%c",&v2);DFSTree2(G,LocateVex(G,v1));push(s,v1);printstack2(s);printf("\n");}void main(){int v;ALGraph G;found=false;initstack(s);Create(G);while(1){for(v=0;v<G.vexnum;v++){visited[v]=false;G.vertices[v].sngle=-2;}tfind=0;system("cls");printf("---------------------\n");printf("1、深度优先遍历\n");printf("2、广度优先遍历\n");printf("3、搜索简单路径\n");printf("4、搜索最短路径\n");printf("---------------------\n");switch (getch()){case'1':DFSTraverse(G);break;case'2': DFSTree(G);break;case'3':Simplepath(G);break;case'4':shortcut(G);break; case'0':exit(0);}system("pause");}}五、运行结果:1、深度优先搜索:2、广度优先搜索:3、简单路径:4、最短路径:。

相关文档
最新文档