数据结构实验六 图的应用及其实现

合集下载

实验六 图的基本操作

实验六 图的基本操作

南京信息工程大学实验(实习)报告图的基本操作一、实验目的1、熟悉图的存储结构2、掌握图的基本操作二、实验准备1、奔腾2计算机或以上机型2、Microsoft Visual C++ 6.0三、实验内容1、建立一张图2、实现深度优先搜索、广度优先搜索遍历四、实验代码#include<stdio.h>#include<conio.h>#include<stdlib.h>typedef struct ArcNode{int adjVex;struct ArcNode *nextArc;}ArcNode;typedef struct VNode{int data;ArcNode *firstArc;}VNode;//创建一张图void CreatGraphic();//深度优先搜索遍历void DFSTraverse(int searchNode);//广度优先搜索遍历void BFSTraverse(int searchNode);//访问标志置零void ClearVisited();void Bound(char ch, int num);//邻接表VNode *adjList;//访问标记数组short *visited;//循环队列, 用于广度优先搜索遍历函数中int *queue;//图的结点数int graphicNode;//用于判断是否创建了图bool creatGraphic;int main(void){char choice;int searchNode;creatGraphic = false;while (true){if (!creatGraphic){system("CLS");printf(" 图的操作\n");Bound('-', 15);printf(" 1. 创建一张图\n");printf(" 0. 退出程序\n");Bound('-', 15);printf(" 请选择: ");fflush(stdin);choice = getchar();switch (choice){case '1':CreatGraphic();break;case '0':printf("\n");system("PAUSE");return 0;default:printf("\n 输入错误, 按任意键后重新输入!");getch();break;}}else{system("CLS");printf(" 图的操作\n");Bound('-', 20);printf(" 1. 深度优先搜索遍历\n");printf(" 2. 广度优先搜索遍历\n");printf(" 0. 退出程序\n");Bound('-', 20);printf(" 请选择: ");fflush(stdin);choice = getchar();switch (choice){case '1':ClearVisited();Lable1:printf("\n 请输入起始搜索的结点序号: ");fflush(stdin);scanf("%d", &searchNode);if (searchNode>=1 && searchNode <=graphicNode){printf(" 深度优先搜索遍历为: ");DFSTraverse(searchNode);}else{printf(" 序号输入错误, 按任意键后重新输入! \n");getch();goto Lable1;}printf("\n\n");system("PAUSE");break;case '2':ClearVisited();Lable2:printf("\n 请输入起始搜索的结点序号: ");scanf("%d", &searchNode);if (searchNode>=1 && searchNode <=graphicNode){printf(" 广度优先搜索遍历为: ");BFSTraverse(searchNode);}else{printf(" 序号输入错误, 按任意键后重新输入! \n");getch();goto Lable2;}printf("\n\n");system("PAUSE");break;case '0':printf("\n");system("PAUSE");return 0;default:printf("\n 输入错误, 按任意键后重新输入!");getch();break;}}}}void CreatGraphic(){int number;int localNode, linkNode;ArcNode *tempNode;Flag:printf("\n 请输入图的顶点数: ");fflush(stdin);scanf("%d", &graphicNode);if (graphicNode <= 0){printf(" 输入错误, 按任意键后重新输入!\n");getch();goto Flag;}if ((adjList=(VNode *)malloc(sizeof(VNode)*graphicNode)) == NULL){printf(" 内存空间不足, 无法创建图!\n");system("PAUSE");exit(0);}if ((visited=(short *)malloc(sizeof(short)*graphicNode)) == NULL){printf(" 内存空间不足, 无法创建访问记录表!\n");system("PAUSE");exit(0);}if ((queue=(int *)malloc(sizeof(int)*graphicNode)) == NULL){printf(" 内存空间不足, 无法创建队列!\n");system("PAUSE");exit(0);}for (number=0; number<graphicNode; ++number){adjList[number].data = number + 1;adjList[number].firstArc = NULL;}printf("\n 请输入所要创建的图中所有相关联的顶点, 格式( 图中一顶点与此顶点相关联的顶点)\n");do{printf(" 请输入( 注意: 输入0 0 结束输入): ");fflush(stdin);scanf("%d %d", &localNode, &linkNode);if (localNode>=1 && localNode<=graphicNode && linkNode>=1 && linkNode<=graphicNode){if ((tempNode = (ArcNode *)malloc(sizeof(ArcNode))) == NULL){printf(" 内存不足, 无法创建图!\n");exit(0);}tempNode->adjVex = linkNode;tempNode->nextArc = adjList[localNode - 1].firstArc;adjList[localNode - 1].firstArc = tempNode;}else{creatGraphic = true;return;}}while(true);}void DFSTraverse(int searchNode){ArcNode *tempNode;visited[searchNode - 1] = 1;printf("%d ", searchNode);tempNode = adjList[searchNode - 1].firstArc;while (tempNode != NULL){if (visited[tempNode->adjVex - 1] == 0){DFSTraverse(tempNode->adjVex);}tempNode = tempNode->nextArc;}}void BFSTraverse(int searchNode){ArcNode *tempNode;int nodeNum;int front = 0, rear = 0;printf("%d ", searchNode);visited[searchNode - 1] = 1;rear = (rear + 1) % graphicNode;queue[rear] = searchNode;while (front != rear){front = (front + 1) % graphicNode;nodeNum = queue[front];tempNode = adjList[nodeNum - 1].firstArc;while (tempNode != NULL){if (visited[tempNode->adjVex - 1] == 0){visited[tempNode->adjVex - 1] = 1;printf("%d ", tempNode->adjVex);rear = (rear + 1) % graphicNode;queue[rear] = tempNode->adjVex;}tempNode = tempNode->nextArc;}}}void ClearVisited(){int cnt;for (cnt=0; cnt<graphicNode; ++cnt){visited[cnt] = 0;}}void Bound(char ch, int num){while (num--){putchar(ch);}putchar('\n');}(本次实验中所用图示意图)(图1:按格式创建图)1876 5 4 3 2(图2:深度优先搜索遍历)(图3:广度优先搜索遍历)五、实验总结…。

实验六 图基本操作的编程实现

实验六  图基本操作的编程实现

盛年不重来,一日难再晨。

及时宜自勉,岁月不待人。

实验六图基本操作的编程实现【实验目的】图基本操作的编程实现要求:图基本操作的编程实现(2学时,验证型),掌握图的建立、遍历、插入、删除等基本操作的编程实现,存储结构可以在顺序结构、链接结构、联合使用多种结构等中任选,也可以全部实现。

也鼓励学生利用基本操作进行一些应用的程序设计。

【实验性质】验证性实验(学时数:2H)【实验内容】编程对图进行存储(邻接矩阵或邻接表都可以,由学生自由选择),之后可以询问任何两个结点之间是否有通路和路径数。

设计一个将图形转成邻接链表的程序。

设计一个深度优先搜索法来查找图形的程序。

设计一个广度优先搜索法来查找一个图形的程序。

鼓励开发出难度更高的程序。

【思考问题】1.图的定义和特性?2.图的主要存储结构是什么?是独立的某种还是多种数据结构的综合?3.图的主要遍历思路是哪些?4.举出图的应用范例?【参考代码】(一)将一个将图转成邻接矩阵的程序./*程序构思:*//*用户输入结点与各个边,再将边转成邻接矩阵。

*/#include<stdio.h>#define Max 6 /* 定义最大可输入的结点个数 */int Graph[Max][Max]; /*图形邻接数组 *//*===============================================*//*输出邻接矩阵数据===============================*//*===============================================*/void print_M_Graph(){int i,j;printf("Vertice");for (i=0;i<Max;i++)printf("%3d",i);printf("\n");for(i=0;i<Max;i++){printf("%4d ",i);for (j=0;j<Max;j++)printf("%3d" );printf("\n");}}/*===============================================*//*以邻接矩阵建立图形=============================*//*===============================================*/void Create_M_Graph(int Verticel,int Vertice2){Graph[Verticel][Vertice2]=1; /* 将矩阵内容设为1 */}/*===============================================*//*主程序=========================================*//*===============================================*/void main(){int Source; /*起始顶点*/int Destination; /*终止顶点*/int i,j;for (i=0;i<Max;i++)for (j=0;j<Max;j++)Graph[i][i]=0;while(1){printf("please input the Edge's source:");scanf("%d",&Source);if(Source ==-1)break;printf("Please input the Edge's Destination:");scanf("%d",&Destination);if(Source==Destination) /* 出错:自身循环*/printf("***Error***: Self Loop!! \n");else if (Source >= Max || Destination >= Max) /* 出错:超出范围*/ printf ("***Error***: out of range!! \n");else /*调用建立邻接数组 */Create_M_Graph(Source,Destination);}printf("##Graph##\n");; /*调用输出邻接数组数据*/}/*希望的结果 *//*please input the Edge's source:0 *//*Please input the Edge's Destination:4 *//*please input the Edge's source:1 *//*Please input the Edge's Destination:0 *//*please input the Edge's source:1 *//*Please input the Edge's Destination:4 *//*please input the Edge's source:2 *//*Please input the Edge's Destination:1 *//*please input the Edge's source:3 *//*Please input the Edge's Destination:2 *//*please input the Edge's source:4 *//*Please input the Edge's Destination:3 *//*please input the Edge's source:-1 *//*##Graph## *//*Vertice 0 1 2 3 4 5 *//* 0 0 0 0 0 1 0 *//* 1 1 0 0 0 1 0 *//* 2 0 1 0 0 0 0 *//* 3 0 0 1 0 0 0 *//* 4 0 0 0 1 0 0 *//* 5 0 0 0 0 0 0 */(二) 将一个将图转成邻接表的程序./*程序构思:*//*用户输入结点与各个边,再将边转成邻接链表。

数据结构实验六 图的应用及其实现

数据结构实验六   图的应用及其实现

实验六图的应用及其实现一、实验目的1.进一步功固图常用的存储结构。

2.熟练掌握在图的邻接表实现图的基本操作。

3.理解掌握AOE网在邻接表上的实现及解决简单的应用问题。

二、实验内容[题目]:从键盘上输入AOE网的顶点和有向边的信息,建立其邻接表存储结构,输出其关键路径和关键路径长度。

试设计程序实现上述AOE网类型定义和基本操作,完成上述功能。

三、实验步骤(一)、数据结构与核心算法的设计描述本实验题目是基于图的基本操作以及邻接表的存储结构之上,着重拓扑排序算法的应用,做好本实验的关键在于理解拓扑排序算法的实质及其代码的实现。

(二)、函数调用及主函数设计以下是头文件中数据结构的设计和相关函数的声明:typedef struct ArcNode // 弧结点{int adjvex;struct ArcNode *nextarc;InfoType info;}ArcNode;typedef struct VNode //表头结点{VertexType vexdata;ArcNode *firstarc;}VNode,AdjList[MAX_VERTEX_NUM];typedef struct //图的定义{AdjList vertices;int vexnum,arcnum;int kind;}MGraph;typedef struct SqStack //栈的定义{SElemType *base;SElemType *top;int stacksize;}SqStack;int CreateGraph(MGraph &G);//AOE网的创建int CriticalPath(MGraph &G);//输出关键路径(三)、程序调试及运行结果分析(四)、实验总结在做本实验的过程中,拓扑排具体代码的实现起着很重要的作用,反复的调试和测试占据着实验大量的时间,每次对错误的修改都加深了对实验和具体算法的理解,自己的查错能力以及其他各方面的能力也都得到了很好的提高。

数据结构图的实验报告

数据结构图的实验报告

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

数据结构实验报告图的应用

数据结构实验报告图的应用

实验题目:图的应用一、实验目的和任务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、掌握树(二叉树、二叉搜索树)的遍历算法和基本操作。

4、学会使用图的数据结构,并实现图的遍历和相关算法。

二、实验环境本次实验使用的编程环境为具体编程环境名称,编程语言为具体编程语言名称。

三、实验内容及步骤(一)线性表的实现与操作1、顺序表的实现定义顺序表的数据结构,包括数组和表的长度等。

实现顺序表的初始化、插入、删除和查找操作。

2、链表的实现定义链表的节点结构,包含数据域和指针域。

实现链表的创建、插入、删除和查找操作。

(二)栈和队列的实现1、栈的实现使用数组或链表实现栈的数据结构。

实现栈的入栈、出栈和栈顶元素获取操作。

2、队列的实现采用循环队列的方式实现队列的数据结构。

完成队列的入队、出队和队头队尾元素获取操作。

(三)树的实现与遍历1、二叉树的创建以递归或迭代的方式创建二叉树。

2、二叉树的遍历实现前序遍历、中序遍历和后序遍历算法。

3、二叉搜索树的操作实现二叉搜索树的插入、删除和查找操作。

(四)图的实现与遍历1、图的表示使用邻接矩阵或邻接表来表示图的数据结构。

2、图的遍历实现深度优先遍历和广度优先遍历算法。

四、实验结果与分析(一)线性表1、顺序表插入操作在表尾进行时效率较高,在表头或中间位置插入时需要移动大量元素,时间复杂度较高。

删除操作同理,在表尾删除效率高,在表头或中间删除需要移动元素。

2、链表插入和删除操作只需修改指针,时间复杂度较低,但查找操作需要遍历链表,效率相对较低。

(二)栈和队列1、栈栈的特点是先进后出,适用于函数调用、表达式求值等场景。

入栈和出栈操作的时间复杂度均为 O(1)。

2、队列队列的特点是先进先出,常用于排队、任务调度等场景。

数据结构实验六 图

数据结构实验六 图

实验六图一、实验目的1、掌握图的基本存储方法和相关术语2、掌握图的两种搜索路径的遍历方法3、理解最小生成树的有关概念及普里姆(Prim)和克鲁斯卡尔算法4、掌握图的有关应用二、实验要求1、认真阅读程序。

2、上机调试,并运行程序。

3、保存和截图程序的运行结果,并结合程序进行分析。

三、实验内容和基本原理1、实验6.1 建立无向图的邻接矩阵存并输出给出一个无向图,求它的邻接矩阵(见参考程序1):2、实验6.2 建立图的邻接存储并在此基础上实现图的深度优先遍历和广度优先遍历#include<stdio.h>#include<stdlib.h>#define MAX 20typedef int VexType;typedef VexType Mgraph[MAX][MAX];void creat_mg(Mgraph G);void output_mg(Mgraph G);Mgraph G1;int n,e,v0;void main(){creat_mg(G1);output_mg(G1);}void creat_mg(Mgraph G){int i,j,k;printf("\n 请输入无向图的顶点数和边数,如: 6,5:");scanf("%d,%d",&n,&e);for(i=1;i<=n;i++)for(j=1;j<=n;j++)G[i][j]=0;for(k=1;k<=e;k++){printf("\n请输入每条边的两个顶点编号,如:2,5 :");scanf("%d,%d",&i,&j);G[i][j]=1;G[j][i]=1;}}void output_mg(Mgraph G){int i,j;for(i=1;i<n;i++){printf("\n");for(j=1;j<=n;j++)printf("%5d",G[i][j]);}printf("\n");}#include<stdio.h>#include<stdlib.h>#define MAX 20typedef int VexType;typedef struct Vnode{VexType data;struct Vnode *next;}Vnode;typedef Vnode Lgraph[MAX];typedef struct{int V[MAX];int front;int rear;}Queue;void creat_L(Lgraph G);void output_L(Lgraph G);void dfsL(Lgraph G,int v);Lgraph Ga;int n,e,visited[MAX];void main(){int v1,i;for(i=0;i<MAX;i++)visited[i]=0;creat_L(Ga);output_L(Ga);printf("\n请输入深度优先遍历的出发点:");scanf("%d",&v1);printf("\n深度优先遍历的结果为:");dfsL(Ga,v1);for(i=0;i<MAX;i++)visited[i]=0;printf("\n请输入广度优先遍历的出发点:");scanf("%d",&v1);printf("\n广度优先遍历的结果为:");dfsL(Ga,v1);}void creat_L(Lgraph G){Vnode *p,*q;int i,j,k;printf("\n请输入图的顶点数和边数:");scanf("%d,%d",&n,&e);for(i=1;i<=n;i++){G[i].data=i;G[i].next=NULL;}for(k=1;k<=e;k++){printf("请输入每条边的关联顶点编号:");scanf("%d,%d",&i,&j);p=(Vnode *)malloc(sizeof(Vnode));p->data=i;p->next=G[j].next;G[j].next=p;q=(Vnode *)malloc(sizeof(Vnode));q->data=j;q->next=G[i].next;G[i].next=q;}}void output_L(Lgraph G){int i;Vnode *p;for(i=1;i<=n;i++){printf("\n与[%d]关联的顶点有:",i);p=G[i].next;while(p!=NULL){printf("%5d",p->data);p=p->next;}}}void initqueue(Queue *q){q->front=-1;q->rear=-1;}int quempty(Queue *q){if(q->front==q->rear){return 1;}else{return 0;}}void enqueue(Queue *q,int e){if((q->rear+1)%MAX==q->front)printf("队列满!\n");else{q->rear=(q->rear+1)%MAX;q->V[q->rear]=e;}}int dequeue(Queue *q){int t;if(q->front==q->rear){printf("队列空!\n");return 0;}else{q->front=(q->front+1)%MAX;t=q->V[q->front];return t;}}void dfsL(Lgraph G,int v){Vnode *p;printf("%d->",G[v].data);visited[v]=1;p=G[v].next;while(p){v=p->data;if(visited[v]==0)dfsL(G,v);p=p->next;}}void bfsL(Lgraph g,int v){int x;Vnode *p;Queue *q=(Queue *)malloc(sizeof(Queue));initqueue(q);printf("\n %d->",g[v].data);visited[v]=1;enqueue(q,v);while(!quempty(q)){x=dequeue(q);p=g[x].next;while(p){v=p->data;if(visited[v]==0){printf("%d->",g[v].data);visited[v]=1;enqueue(q,v);}p=p->next;}}printf("\n");}四、实验验证与练习1、在N条边的无向图的邻接表存储中,边表中结点的总数为()。

实验六 图及其应用

实验六 图及其应用

实验六图及其应用数据结构实验六图及其应用1、实验目的? 熟练掌握图的两种存储结构(邻接矩阵和邻接表)的表示方法 ? 掌握图的基本运算及应用? 加深对图的理解,逐步培养解决实际问题的编程能力2、实验内容:采用邻接表或邻接矩阵方式存储图,实现图的深度遍历和广度遍历;用广度优先搜索方法找出从一顶点到另一顶点边数最少的路径。

1.问题描述:利用邻接表存储结构,设计一种图(有向或无向),并能够对其进行如下操作:1) 创建一个可以随机确定结点数和弧(有向或无向)数的图; 2) 根据图结点的序号,得到该结点的值;3) 根据图结点的位置的第一个邻接顶点的序号,以及下一个邻接顶点的序号;4) 实现从第v 个顶点出发对图进行深度优先递归遍历; 5) 实现对图作深度优先遍历;6) 实现对图进行广度优先非递归遍历; 编写主程序,实现对各不同的算法调用。

2.实现要求:(以邻接表存储形式为例)编写图的基本操作函数::对图的各项操作一定要编写成为C(C++)语言函数,组合成模块化的形式,每个算法的实现要从时间复杂度和空间复杂度上进行评价。

1)“建立图的邻接表算法”:CreateGraph(ALGraph *G) 操作结果:采用邻接表存储结构,构造没有相关信息的图G2)“邻接表表示的图的递归深度优先遍历算法”:DFSTraverse(ALGraphG,void(*Visit)(char*)) 初始条件:图G 已经存在;操作结果:返回图的按深度遍历的结果。

3)“邻接表表示的图的广度优先遍历算法”: BFSTraverse(ALGraphG,void(*Visit)(char*)) 初始条件:图G 已经存在;操作结果:返回图的按广度遍历的结果。

4)“邻接表从某个结点开始的广度优先遍历算法”:BFS(ALGraph G, int v)初始条件:图G 已经存在;操作结果:返回图从某个结点开始的按广度遍历的结果。

分析: 修改输入数据,预期输出并验证输出的结果,加深对有关算法的理解。

数据结构实验六 图结构及其应用

数据结构实验六 图结构及其应用

实验七图结构及其应用一、实验目的1.掌握图类的邻接矩阵存储结构的实现;2.掌握图的基本操作,包括图的建立、广度优先遍历和深度优先遍历算法;3.掌握求最短路径的Dijkastra算法。

二、实验要求1.复习课本中第7章关于图的相关知识内容;2.用C++语言完成算法和程序设计并且调试通过;三、实验题目与要求1.图的遍历详细描述:利用以提供的源程序素材,实现对不多于30个结点的图的建立以及广度优先和深度优先遍历算法。

具体功能要求:从键盘中输入网中顶点的个数,以及顶点的数据值,并以顶点的输入次序作为顶点的编号输入顶点与顶点之间的邻接边的权值(注:若为无向图,则每条边可由两条方向相反的有向边构成);若无边相连则已设定的权值最大值MaxWeight=1000代替。

利用顶点与边的信息建立网的邻接矩阵,并第一个输入的顶点为原点对网进行深度优先和广度优先遍历,并输入遍历的顶点序列。

例:如下图7-1图所示,则输入为:6ABCDEF18A B 34A E 12B A 34B C 46B F 19C B 46C D 17C F 25D C 17D E 38D F 25E A 12E D 38E F 26F B 19F D 25F C 25F E 26图7-1 网的图示表示在提供的程序模板中,完成以下函数,实现上述功能;(1)DFSTraverse (MGraph G)功能描述:对网进行深度优先遍历,网可以非连通(2)BFSTraverse (MGraph G)功能描述:对网进行广度优先遍历,网可以非连通2.最短路径求解详细描述:在第一题的基础上,Dijkastra算法求解从第A个顶点到其余各个顶点的最短路径的所经过的顶点以及路径的长度。

例:如图7-1所示,则该求出顶点A到其余个顶点的最短路径所经过的顶点,以及路径的长度;输出如下所示:A->B: A B 34A->C: A E F C 63A->D: A E D 50A->E: A E 12A->F: A E F 38在提供的程序模板中,完成以下函数,实现上述功能;void dijkstra(MGraph G, int vs )3.验证练习先对下图7-2和7-3进行深度和广度优先遍历,并求出以A作为源点求最短路径的结果。

数据结构--图的应用及其实现

数据结构--图的应用及其实现

实验六图的应用及其实现(相关知识点:拓扑排序、关键路径、最小生成树和最短路径)一、实验目的1.进一步功固图常用的存储结构。

2.熟练掌握在图的邻接表实现图的基本操作。

3.理解掌握AOV网、AOE网在邻接表上的实现以及解决简单的应用问题。

二、实验内容一>.基础题目:(本类题目属于验证性的,要求学生独立完成)[题目一]:从键盘上输入AOV网的顶点和有向边的信息,建立其邻接表存储结构,然后对该图拓扑排序,并输出拓扑序列. 试设计程序实现上述AOV网的类型定义和基本操作,完成上述功能。

测试数据:教材图7.28[题目二]:从键盘上输入AOE网的顶点和有向边的信息,建立其邻接表存储结构,输出其关键路径和关键路径长度。

试设计程序实现上述AOE网类型定义和基本操作,完成上述功能。

测试数据:教材图7.29二>.简单应用题目:(ACM/ICPC训练题,本类题目属于设计性的,要求学生三人为一个团队,分工协作完成))【题目三】高速公路描述某国共有n个城市(n不超过200),有些城市之间直接有一条高速公路相连,高速公路都是双向的,总共有m条。

每条高速公路都有自己的载重限制,即载重最大值。

通过车辆的载重不能超过公路的载重限制。

如今我们想了解的是,从某一起点城市出发,到达目标城市,车辆最多能带多重的货物。

输入输入的第一行为两个整数n和m。

以下有m行,每行三个整数描述一条公路,分别是首尾相连的城市以及载重限制。

然后是一个整数k,即问题个数。

接下来k行描述k个问题,每行两个整数表示起点城市和目标城市。

问题数不超过一百。

输出输出包括k行,每行对应一个问题,输出从起点到目标的最大载重量。

如果两城市间无路径则输出-1。

样例输入3 31 2 1002 3 1001 3 5021 32 3样例输出100100【题目四】最短的旅程描述在Byteland有n个城市(编号从1到n),它们之间通过双向的道路相连。

Byteland 的国王并不大方,所以,那里只有n -1条道路,但是,它们的连接方式使得从任意城市都可以走到其他的任何城市。

【学生版】实验六 图基本操作的编程实现

【学生版】实验六  图基本操作的编程实现

实验六图基本操作的编程实现【实验目的】图基本操作的编程实现要求:图基本操作的编程实现(2学时,验证型),掌握图的建立、遍历、插入、删除等基本操作的编程实现,存储结构可以在顺序结构、链接结构、联合使用多种结构等中任选,也可以全部实现。

也鼓励学生利用基本操作进行一些应用的程序设计。

【实验性质】验证性实验(学时数:2H)【实验内容】编程对图进行存储(邻接矩阵或邻接表都可以,由学生自由选择),之后可以询问任何两个结点之间是否有通路和路径数。

设计一个将图形转成邻接链表的程序。

设计一个深度优先搜索法来查找图形的程序。

设计一个广度优先搜索法来查找一个图形的程序。

鼓励开发出难度更高的程序。

【思考问题】1.图的定义和特性?2.图的主要存储结构是什么?是独立的某种还是多种数据结构的综合?3.图的主要遍历思路是哪些?4.举出图的应用范例?【参考代码】(一)基础篇//将一个图采用邻接表存储,并在该存储方法上进行深度优先遍历.//程序构思://用户键盘输入结点与各条边,再将边转成邻接链表。

//然后对采用邻接表表示的图进行深度优先遍历。

#include<stdio.h>#include <stdlib.h>#define vertexnum 100 //定义最大可输入的结点个数typedef struct node //定义图形的顶点结构{int vertex; //图中的顶点信息为数字struct node *next;}Graph;Graph head[vertexnum]; //邻接表的表头结点int Visited[vertexnum]; //遍历记录void Create_l_Graph(int Vertex1,int Vertex2,int no){ //以邻接链表建立图形Graph *searchP; //结点声明Graph *New; //新结点声明New=(Graph *)malloc(sizeof(struct node));if (New!= NULL ){New->vertex=Vertex2;New->next=NULL;searchP=&(head[Vertex1]);while(searchP->next!=NULL)searchP=searchP->next;searchP->next =New;if(no==0){New=(Graph *)malloc(sizeof(struct node));New->vertex=Vertex1;New->next=NULL;searchP=&(head[Vertex2]);while(searchP->next!=NULL)searchP=searchP->next;searchP->next =New;}}}void showmenu(){ //显示菜单printf(" 欢迎使用图的操作演示软件\n");printf("\t1、创建图的邻接表\n");printf("\t2、图的输出\n");printf("\t3、图的深度优先遍历\n");printf("\t4、退出程序\n");}void print_l_graph(Graph *head){ //输出邻接链表的数据Graph *searchP;searchP=head->next;while(searchP!=NULL){}printf("\n");}void DFS(int vertex){ //深度优先遍历Graph *SearchP; //结点声明//标记某个结点已遍历过printf("[%d]==>",vertex);SearchP=head[vertex].next;while(SearchP!=NULL){if( ) //判断结点未被遍历过//递归调用深度优先遍历函数 SearchP=SearchP->next; //下一个邻接点}}void main(){int source; //图中一条边的起始顶点int destination; //图中一条边的终止顶点int i,j;int vermax; //定义图中最大的顶点数int edgemax; //定义图中最大的边数int choice;int no;while(1){showmenu();printf(" 请输入你的选择:");scanf("%d",&choice);fflush(stdin);//清除键盘缓冲区switch(choice){case 1:printf("请输入图的类别(有向图-1,无向图-0):");scanf("%d",&no);printf("请输入图中的总顶点数和边数:");scanf("%d%d",&vermax,&edgemax);for(i=1;i<vermax;i++){head[i].vertex = i;head[i].next = NULL;}for(i=1;i<=edgemax;i++){printf("请输入第%d条边的起点:",i);scanf("%d",&source);printf("请输入第%d条边的终点:",i);scanf("%d",&destination);if(source==destination)printf("输入有误!\n");//出错:自身循环else //调用建立邻接链表 Create_l_Graph(source,destination,no);}printf("图创建成功,按任意键继续…\n");getch();system("cls");break;case 2:printf("图的邻接表如下:\n");for(i=1;i<=vermax;i++){printf("顶点[%d]:",i);print_l_graph(&head[i]);//调用输出邻接链表数据}printf("\n");system("pause");system("cls");break;case 3:for(i=1;i<=vermax;i++)Visited[i]=0;printf("请输入遍历的起点:");scanf("%d",&source);printf("图的深度优先遍历结果为:\n");DFS(source);printf("END\n");system("pause");system("cls");break;case 4:return;default:printf("你的输入有误,请从新输入!\n");system("pause");system("cls");}}}(二)提高篇//将一个图采用邻接表存储,并在该存储方法上进行深度优先遍历..//程序构思://用户键盘输入结点与各个边,再将边转成邻接链表。

数据结构实验六图结构及其应用

数据结构实验六图结构及其应用

实验七图结构及其应用一、实验目的1.掌握图类的邻接矩阵存储结构的实现;2.掌握图的基本操作,包括图的建立、广度优先遍历和深度优先遍历算法;3.掌握求最短路径的Dijkastra算法。

二、实验要求1.复习课本中第7章关于图的相关知识内容;2.用C+叫言完成算法和程序设计并且调试通过;三、实验题目与要求1.图的遍历详细描述:利用以提供的源程序素材,实现对不多于30个结点的图的建立以及广度优先和深度优先遍历算法。

具体功能要求:从键盘中输入网中顶点的个数,以及顶点的数据值,并以顶点的输入次序作为顶点的编号输入顶点与顶点之间的邻接边的权值(注:若为无向图,则每条边可由两条方向相反的有向边构成);若无边相连则已设定的权值最大值MaxWeight=100O弋替。

利用顶点与边的信息建立网的邻接矩阵,并第一个输入的顶点为原点对网进行深度优先和广度优先遍历,并输入遍历的顶点序列。

例:如下图7-1图所示,则输入为:6ABCDEF18A B 34A E 12B A 34B C 46B F 19C B 46C D 17C F 25D C 17D E 38D F 25E A 12E D 38E F 26F B 19F D 25F C 25F E 26在提供的程序模板中,完成以下函数,实现上述功能;(1)DFSTraverse (MGraph G)功能描述:对网进行深度优先遍历,网可以非连通(2)BFSTraverse (MGraph G)功能描述:对网进行广度优先遍历,网可以非连通2.最短路径求解详细描述:在第一题的基础上,Dijkastra算法求解从第A个顶点到其余各个顶点的最短路径的所经过的顶点以及路径的长度。

例:如图7-1所示,则该求出顶点A0其余个顶点的最短路径所经过的顶点,以及路径的长度;输出如下所示:A->B: A B 34A->C: A E F C 63A->D: A E D 50A->E: A E 12A->F: A E F 38在提供的程序模板中,完成以下函数,实现上述功能;void dijkstra(MGraph G, int vs )3.验证练习先对下图7-2和7-3进行深度和广度优先遍历,并求出以A作为源点求最短路径的结果。

数据结构 图实验报告

数据结构 图实验报告

数据结构图实验报告数据结构图实验报告引言:数据结构是计算机科学中非常重要的一个概念,它用于存储和组织数据,使得数据的操作更加高效和方便。

图是一种常见的数据结构,它由节点和边组成,用于表示各种实际问题中的关系和连接。

本实验旨在通过实际操作,深入理解图的基本概念和常见操作。

实验目的: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.理解图的概念并熟悉有关术语。

2.熟练掌握邻接矩阵表示法和邻接表表示法。

3.掌握连通图遍历的基本思想和算法。

4.掌握最小生成树的有关概念和算法实现。

5.掌握最短路径有关概念和算法。

6.掌握拓扑排序的概念及实现。

二. 实验内容1.对给定的图,用邻接矩阵实现该图的深度优先搜索遍历。

2.对给定的图,用邻接矩阵实现该图的广度优先搜索遍历。

3.对给定的图,用邻接表实现该图的深度优先搜索遍历。

4.对给定的图,用邻接表实现该图的广度优先搜索遍历。

三. 文献综述数据结构(C语言版)习题解答及实训指导------------李根强、谢月娥四. 实验思路和技术路线(数据结构及算法)(1,2)算法设计:首先定义图的类型为结构型,包含图中的顶点信息和邻接矩阵两项信息,然后将输入边的信息建立邻接矩阵,再将深度搜索优先遍历和广度优先搜索遍历写成子函数的形式,在主函数中调用他们;(3,4)算法设计:首先定义图的邻接表数据类型,建立该图的邻接表,然后再用子函数写出深度优先搜索遍历和广度优先搜索遍历的算法,在主函数中调用它;五. 实验结果分析及心得(1)对给定的图,用邻接矩阵实现该图的深度优先和广度优先搜索遍历:<1 给定的图如下:< 2 广度优先和深度优先遍历程序如下:#include<stdio.h>#define n 8 //图中顶点数#define e 15 //图中边数#define elemtype intint visited[n+1]; //访问标志数组,为false表示未访问,为true表示已访问struct graph //定义图的数据类型{elemtype v[n+1]; //存放顶点信息 v1,v2,...,vn,不使用v[0]存储空间int arcs[n+1][n+1]; //邻接矩阵}g;void creatadj() //建立邻接矩阵{int i,j,k;printf("请输入%d个顶点信息\n",n);for(k=1;k<=n;k++)scanf("%d",&g.v[k]); //输入顶点信息for(i=1;i<=n;i++)for(j=1;j<=n;j++)g.arcs[i][j]=0;for(k=1;k<=e;k++){printf("请输入第%d条边,共%d条边",k,e);scanf("%d%d",&i,&j); //输入一条边(i,j)g.arcs[i][j]=1;g.arcs[j][i]=1;}}void dfs(int i) //从顶点i出发进行深度优先搜索遍历 {int j;printf("%d",g.v[i]); //输出访问顶点visited[i]=1; //全局数组访问标记置1表示已访问for(j=1;j<=n;j++)if((g.arcs[i][j]==1)&&(!visited[j]))dfs(j);}void bfs(int i) //从顶点i出发进行广度优先搜索遍历{int q[n+1]; //q为队列int f,r,j; //f,r分别为队列头指针、尾指针f=r=0; //设置空队列printf("%d",g.v[i]); //输出访问顶点visited[i]=1; //全局数组标记置1表示已访问r++;q[r]=i; //入队列while(f<r){f++;i=q[f]; //出队列for(j=1;j<=n;j++)if((g.arcs[i][j]==1)&&(!visited[j])){printf("%d",g.v[j]);visited[j]=1;r++;q[r]=j; //入队列}}}main(){int i,j;int yn=1;creatadj(); //建立邻接矩阵for(i=1;i<=n;i++) //输出邻接矩阵{for(j=1;j<=n;j++)printf("%d",g.arcs[i][j]);printf("\n");}while(yn==1){for(i=1;i<=n;i++)visited[i]=0;printf("请输入深度优先搜索开始访问的顶点");scanf("%d",&i);printf("\n");printf("从%d出发的深度优先搜素遍历序列为\n",i);dfs(i);printf("\n继续进行深度优先搜索吗(1/2)?");scanf("%d",&yn);}yn=1;while(yn==1){for(i=1;i<=n;i++)visited[i]=0;printf("请输入广度优先搜索开始访问的顶点");scanf("%d",&i);printf("\n");printf("从%d出发的广度优先搜索遍历序列为\n",i);bfs(i);printf("\n继续进行广度优先搜索吗 (1/2) ?");scanf("%d",&yn);}}运行结果:#define e 15 //图中边数#define elemtype intint visited[n+1];istruct link{elemtype data;struct link *next;};struct graph{struct link a[n+1];}g;void creatlink(){int i,j,k;struct link *s;for(i=1;i<=n;i++){g.a[i].data=i;g.a[i].next=NULL;}for(k=1;k<=e;k++){printf("请输入一条边");scanf("%d%d",&i,&j);s=(struct link *)malloc(sizeof(struct link));s->data=j;s->next=g.a[i].next;g.a[i].next=s;s=(struct link *)malloc(sizeof(struct link));s->data=i;s->next=g.a[j].next;g.a[j].next=s;}}void dfs1(int i){struct link *p;printf("%d",g.a[i].data);visited[i]=1;p=g.a[i].next;while(p!=NULL){if(!visited[p->data])dfs1(p->data);p=p->next;}}void bfs1(int i){int q[n+1];int f,r;struct link *p;f=r=0;printf("%d",g.a[i].data);visited[i]=1;r++;q[r]=i;while(f<r){f++;i=q[f];p=g.a[i].next;while(p!=NULL){if(!visited[p->data]){printf("%d",g.a[p->data].data);visited[p->data]=1;r++;q[r]=p->data;}p=p->next;}}}main(){struct link *p;int yn=1,i;creatlink();while(yn==1){for(i=1;i<=n;i++){p=g.a[i].next;printf("%d->",g.a[i].data);while(p->next!=NULL){printf("%d->",p->data);p=p->next;}printf("%d\n",p->data);}while(yn==1){for(i=1;i<=n;i++)visited[i]=0;printf("请输入深度优先搜索开始访问的顶点");scanf("%d",&i);printf("\n");printf("从%d出发的深度优先搜索遍历序列为\n",i);dfs1(i);printf("\n继续进行深度优先搜索吗(1/2)?");scanf("%d",&yn);}yn=1;while(yn==1){for(i=1;i<=n;i++)。

数据结构-实验六讲义(2)-图的基本操作

数据结构-实验六讲义(2)-图的基本操作

实验6:图的操作算法
一、实验目的
1. 熟悉各种图的存储结构(邻接矩阵和邻接表)。

2.掌握图的深度优先和广度优先遍历算法。

3.掌握克鲁斯卡尔算法生成最小生成树的方法。

4.掌握狄克斯特拉算法计算最短路径和最短路径长度的方法。

二、实验内容
1. 编写一个程序,输出带权图的邻接矩阵,并能将该邻接矩阵转换成相应的邻接表,
并输出该邻接表,带权图如下图所示。

5
1
43
2
5
4
8
3
1
5
5
6
9
7
具体效果如下:
2. 编写一个程序,输出下面带权有向图的邻接表,并根据该邻接表,实现图的深度优先遍历算法,具体要求如下:
(1)从顶点0开始的深度优先遍历序列(递归算法)
(2)从顶点0开始的深度优先遍历序列(非递归算法)
(3)从顶点0开始的广度优先遍历序列(思考)
5
1
43
2
5
4
8
3
1
5
5
6
9
7
具体效果如下:
三、思考题
假设图G采用邻接表存储,试设计一个算法,判断下面无向图G是否为一棵树。

若为树,返回真,否则返回假。

(提示:一个无向图G是一棵树的条件是G必须是无回路的连通图或是有n-1条边的连通图)
1
20
4
3
具体效果如下:
若无向图如右图所示:
1
20
4
3具体效果如下:
四、实验要求
1.独立完成实验程序的编写与调试;
2.实验完成后填写实验报告,学习委员按学号从小到大的顺序提交。

数据结构实验报告 图

数据结构实验报告 图

数据结构实验报告图一、实验目的本次实验的主要目的是深入理解和掌握图这种数据结构的基本概念、存储结构和相关算法,并通过实际编程实现来提高对图的操作和应用能力。

二、实验环境本次实验使用的编程语言为C++,开发工具为Visual Studio 2019。

三、实验内容(一)图的存储结构1、邻接矩阵邻接矩阵是用一个二维数组来表示图中顶点之间的关系。

如果顶点i 和顶点 j 之间有边相连,则数组中对应的元素值为 1;否则为 0。

这种存储结构简单直观,适用于顶点数较少且边数较多的稠密图。

2、邻接表邻接表是为图的每个顶点建立一个单链表,链表中存储的是与该顶点相邻的顶点信息。

这种存储结构在存储空间上比较节省,适用于顶点数较多且边数较少的稀疏图。

(二)图的遍历算法1、深度优先遍历(DepthFirst Search,简称 DFS)从图中的某个顶点出发,沿着一条路径尽可能深地访问顶点,直到无法继续前进,然后回溯到上一个未完全访问的顶点,继续进行深度优先搜索。

2、广度优先遍历(BreadthFirst Search,简称 BFS)从图中的某个顶点出发,先访问其所有相邻的顶点,然后再依次访问这些相邻顶点的相邻顶点,以此类推,逐层向外扩展。

(三)图的最短路径算法1、迪杰斯特拉(Dijkstra)算法用于求解单源最短路径问题,即从一个给定的源顶点到图中其他所有顶点的最短路径。

2、弗洛伊德(Floyd)算法用于求解任意两个顶点之间的最短路径。

四、实验步骤(一)邻接矩阵的实现```cppinclude <iostream>using namespace std;const int MAX_VERTEX_NUM = 100;class Graph {private:int vertexNum;int edgeNum;int adjMatrixMAX_VERTEX_NUMMAX_VERTEX_NUM;public:Graph(int vNum) {vertexNum = vNum;edgeNum = 0;for (int i = 0; i < vertexNum; i++){for (int j = 0; j < vertexNum; j++){adjMatrixij = 0;}}}void addEdge(int i, int j) {if (i >= 0 && i < vertexNum && j >= 0 && j < vertexNum) {adjMatrixij = 1;adjMatrixji = 1;edgeNum++;}}void printGraph(){for (int i = 0; i < vertexNum; i++){for (int j = 0; j < vertexNum; j++){cout << adjMatrixij <<"";}cout << endl;}}};int main(){Graph g(5);gaddEdge(0, 1);gaddEdge(0, 2);gaddEdge(1, 2);gaddEdge(2, 3);gaddEdge(3, 4);gprintGraph();return 0;}```(二)邻接表的实现```cppinclude <iostream>include <vector>using namespace std;const int MAX_VERTEX_NUM = 100; class Graph {private:int vertexNum;vector<int> adjListMAX_VERTEX_NUM;public:Graph(int vNum) {vertexNum = vNum;}void addEdge(int i, int j) {if (i >= 0 && i < vertexNum && j >= 0 && j < vertexNum) {adjListipush_back(j);adjListjpush_back(i);}}void printGraph(){for (int i = 0; i < vertexNum; i++){cout << i <<":";for (int j = 0; j < adjListisize(); j++){cout << adjListij <<"";}cout << endl;}}};int main(){Graph g(5);gaddEdge(0, 1);gaddEdge(0, 2);gaddEdge(1, 2);gaddEdge(2, 3);gaddEdge(3, 4);gprintGraph();return 0;}```(三)深度优先遍历的实现```cppinclude <iostream>include <vector>using namespace std;const int MAX_VERTEX_NUM = 100;class Graph {private:int vertexNum;vector<int> adjListMAX_VERTEX_NUM;bool visitedMAX_VERTEX_NUM;public:Graph(int vNum) {vertexNum = vNum;for (int i = 0; i < vertexNum; i++){visitedi = false;}}void addEdge(int i, int j) {if (i >= 0 && i < vertexNum && j >= 0 && j < vertexNum) {adjListipush_back(j);adjListjpush_back(i);}}void DFS(int v) {visitedv = true;cout << v <<"";for (int i = 0; i < adjListvsize(); i++){int u = adjListvi;if (!visitedu) {DFS(u);}}}void DFSTraversal(){for (int v = 0; v < vertexNum; v++){if (!visitedv) {DFS(v);}}}};int main(){Graph g(5);gaddEdge(0, 1);gaddEdge(0, 2);gaddEdge(1, 2);gaddEdge(2, 3);gaddEdge(3, 4);gDFSTraversal();return 0;}```(四)广度优先遍历的实现```cppinclude <iostream>include <queue>include <vector>using namespace std;const int MAX_VERTEX_NUM = 100; class Graph {private:int vertexNum;vector<int> adjListMAX_VERTEX_NUM; bool visitedMAX_VERTEX_NUM; public:Graph(int vNum) {vertexNum = vNum;for (int i = 0; i < vertexNum; i++){visitedi = false;}}void addEdge(int i, int j) {if (i >= 0 && i < vertexNum && j >= 0 && j < vertexNum) {adjListipush_back(j);adjListjpush_back(i);}}void BFS(int v) {queue<int> q;visitedv = true;qpush(v);while (!qempty()){int u = qfront();qpop();cout << u <<"";for (int i = 0; i < adjListusize(); i++){int w = adjListui;if (!visitedw) {visitedw = true;qpush(w);}}}}void BFSTraversal(){for (int v = 0; v < vertexNum; v++){if (!visitedv) {BFS(v);}}}};int main(){Graph g(5);gaddEdge(0, 1);gaddEdge(0, 2);gaddEdge(1, 2);gaddEdge(2, 3);gaddEdge(3, 4);gBFSTraversal();return 0;}```(五)迪杰斯特拉算法的实现```cppinclude <iostream>include <climits>include <vector>using namespace std;const int MAX_VERTEX_NUM = 100; const int INFINITY = INT_MAX; class Graph {private:int vertexNum;int adjMatrixMAX_VERTEX_NUMMAX_VERTEX_NUM;int distanceMAX_VERTEX_NUM;bool visitedMAX_VERTEX_NUM;public:Graph(int vNum) {vertexNum = vNum;for (int i = 0; i < vertexNum; i++){for (int j = 0; j < vertexNum; j++){adjMatrixij = INFINITY;}distancei = INFINITY;visitedi = false;}}void addEdge(int i, int j, int weight) {if (i >= 0 && i < vertexNum && j >= 0 && j < vertexNum) {adjMatrixij = weight;adjMatrixji = weight;}}int minDistance(){int min = INFINITY;int minIndex =-1;for (int v = 0; v < vertexNum; v++){if (!visitedv && distancev <= min) {min = distancev;minIndex = v;}}return minIndex;}void dijkstra(int src) {distancesrc = 0;for (int count = 0; count < vertexNum 1; count++){int u = minDistance();visitedu = true;for (int v = 0; v < vertexNum; v++){if (!visitedv && adjMatrixuv!= INFINITY && distanceu!=INFINITY && distanceu + adjMatrixuv < distancev) {distancev = distanceu + adjMatrixuv;}}}for (int i = 0; i < vertexNum; i++){cout <<"源点"<< src <<"到顶点"<< i <<"的最短距离为: "<< distancei << endl;}}};int main(){Graph g(5);gaddEdge(0, 1, 2);gaddEdge(0, 2, 4);gaddEdge(1, 2, 1);gaddEdge(1, 3, 7);gaddEdge(2, 3, 3);gaddEdge(3, 4, 5);gdijkstra(0);return 0;}```(六)弗洛伊德算法的实现```cppinclude <iostream>include <climits>using namespace std;const int MAX_VERTEX_NUM = 100; const int INFINITY = INT_MAX; class Graph {private:int vertexNum;int adjMatrixMAX_VERTEX_NUMMAX_VERTEX_NUM;int distanceMAX_VERTEX_NUMMAX_VERTEX_NUM;public:Graph(int vNum) {vertexNum = vNum;for (int i = 0; i < vertexNum; i++){for (int j = 0; j < vertexNum; j++){adjMatrixij = INFINITY;}}}void addEdge(int i, int j, int weight) {if (i >= 0 && i < vertexNum && j >= 0 && j < vertexNum) {adjMatrixij = weight;}}void floyd(){for (int i = 0; i < vertexNum; i++){for (int j = 0; j < vertexNum; j++){distanceij = adjMatrixij;}}for (int k = 0; k < vertexNum; k++){for (int i = 0; i < vertexNum; i++){for (int j = 0; j < vertexNum; j++){if (distanceik!= INFINITY && distancekj!= INFINITY &&distanceik + distancekj < distanceij) {distanceij = distanceik + distancekj;}}}}for (int i = 0; i < vertexNum; i++){for (int j = 0; j < vertexNum; j++){if (distanceij == INFINITY) {cout <<"顶点"<< i <<"到顶点"<< j <<"的距离为: 无穷大" << endl;} else {cout <<"顶点"<< i <<"到顶点"<< j <<"的距离为: "<< distanceij << endl;}}}}};int main(){Graph g(4);gaddEdge(0, 1, 5);gaddEdge(0, 3, 10);gaddEdge(1, 2, 3);gaddEdge(2, 3, 1);gfloyd();return 0;}```五、实验结果分析(一)邻接矩阵和邻接表的比较邻接矩阵的优点是可以快速判断两个顶点之间是否有边相连,时间复杂度为O(1)。

数据结构图实验报告

数据结构图实验报告

数据结构图实验报告一、实验目的本次实验的主要目的是深入理解和掌握数据结构图的基本概念、原理和操作方法,通过实际编程和操作,提高对数据结构的应用能力和解决问题的能力。

二、实验环境本次实验使用的编程语言为C++,开发环境为Visual Studio 2019。

三、实验内容(一)线性表1、顺序表实现顺序表的创建、插入、删除、查找等基本操作。

分析顺序表在不同操作下的时间复杂度。

2、链表实现单链表、双向链表的创建、插入、删除、查找等基本操作。

比较单链表和双向链表在操作上的优缺点。

(二)栈和队列1、栈实现顺序栈和链式栈。

用栈解决表达式求值问题。

2、队列实现顺序队列和链式队列。

用队列模拟银行排队问题。

(三)树1、二叉树实现二叉树的创建、遍历(前序、中序、后序)。

计算二叉树的深度和节点数。

2、二叉搜索树实现二叉搜索树的插入、删除、查找操作。

分析二叉搜索树的性能。

(四)图1、图的存储实现邻接矩阵和邻接表两种图的存储方式。

比较两种存储方式的优缺点。

2、图的遍历实现深度优先遍历和广度优先遍历算法。

用图的遍历解决最短路径问题。

四、实验步骤(一)线性表1、顺序表定义一个数组来存储顺序表的元素,并使用一个变量记录当前表的长度。

插入操作时,需要判断插入位置是否合法,如果合法则将插入位置后的元素依次向后移动一位,然后将新元素插入指定位置。

删除操作时,先判断删除位置是否合法,合法则将删除位置后的元素依次向前移动一位,并更新表的长度。

查找操作通过遍历数组来实现。

分析不同操作的时间复杂度,插入和删除操作在最坏情况下为O(n),查找操作在平均情况下为 O(n/2)。

2、链表对于单链表,定义一个节点结构体,包含数据域和指向下一个节点的指针域。

通过操作指针来实现插入、删除和查找操作。

双向链表则在节点结构体中增加指向前一个节点的指针,使得操作更加灵活,但也增加了空间复杂度。

比较单链表和双向链表在插入、删除操作中指针的调整过程,得出双向链表在某些情况下更方便,但空间开销较大的结论。

实验六 图及图的操作

实验六 图及图的操作

实验报告六图及图的操作实验一、实验目的:1、掌握图的基本概念和术语2、掌握图的存储结构及创建算法。

3、掌握图的遍历算法(递归或非递归算法)。

二、实验内容:1、图邻接矩阵存储结构表示及基本操作算法实现(1)邻接矩阵存储结构类定义:自定义如下:public interface LList<T> {boolean isEmpty();int length();T get(int i);void set(int i,T x);void insert(int i,T x);void append(T x);T remove(int i);void removeAll();}public class SeqList<T> implements LList<T> {private Object[] element;private int len;public SeqList(int size){this.element=new Object[size];this.len = 0;}public SeqList(SeqList<T> list){this(list.len);this.len=list.len;}public SeqList(){this(64);}public boolean isEmpty(){return this.len==0;}public int length(){return this.len;}public T get(int i){if(i>=0&&i<this.len)return (T)this.element[i];return null;}public void set(int i, T x){if(x==null)return;if(i>=0&&i<this.len)this.element[i] = x;elsethrow new IndexOutOfBoundsException(i+""); }public String toString(){String str = "(";if(this.len>0)str += this.element[0].toString();for(int i=1;i<this.len;i++)str +=","+this.element[i].toString();return str+")";}public void insert(int i, T x){if(x==null)return;if(this.len==element.length){Object[] temp = this.element;this.element=new Object[temp.length*2];for(int j=0;j < temp.length;i++)this.element[j]=temp[j];}if(i<0)i=0;if(i>this.len)i=this.len;for(int j=this.len-1;j>=i;j--)this.element[j+1] = this.element[j];this.element[i]=x;this.len++;}public void append(T x){insert(this.len,x);}public T remove(int i){if(this.len==0||i<0||i>=len)return null;T old = (T)this.element[i];for(int j=0;j<this.len-1;j++)this.element[j] = this.element[j+1];this.element[this.len-1]=null;this.len--;return old;}public void removeAll(){this.len=0;}}(2)创建邻接矩阵算法创建无向图邻接矩阵算法:public class MatrixGraph<T> {protected SeqList<T> vertexlist;protected int[][] adjmatrix;private final int Max=0;public MatrixGraph(int size){size=size<10?10:size;this.vertexlist=new SeqList<T>(size);this.adjmatrix=new int[size][size];for(int i=0;i<size;i++)for(int j=0;j<size;j++)this.adjmatrix[i][j]=(i==j)?0:Max;}public MatrixGraph(T[] vertices,Edge[] edges){ this(vertices.length);if(vertices==null)return;for(int i=0;i<vertices.length;i++)insertVertex(vertices[i]);if(edges!=null)for(int j=0;j<edges.length;j++)insertEdge(edges[j]);}public int vertexCount(){return this.vertexlist.length();}public T get(int i){return this.vertexlist.get(i);}public int getWeight(int i,int j){return this.adjmatrix[i][j];}public String toString(){String str="顶点集合:"+this.vertexlist.toString()+"\n 邻接矩阵:\n";int n=this.vertexCount();for(int i=0;i<n;i++){for(int j=0;j<n;j++)str+=this.adjmatrix[i][j]==Max?" 0":" "+this.adjmatrix[i][j];str+="\n";}return str;}public int insertVertex(T x){this.vertexlist.append(x);if(this.vertexCount()>this.adjmatrix.length){int temp[][]=adjmatrix,i,j;this.adjmatrix=new int[temp.length*2][temp.length^2];for(i=0;i<temp.length;i++){for(j=0;j<temp.length;j++)this.adjmatrix[i][j]=temp[i][j];for(j=temp.length;j<temp.length*2;i++)this.adjmatrix[i][j]=Max;}for(i=temp.length;i<temp.length*2;i++)for(j=0;j<temp.length*2;j++)this.adjmatrix[i][j]=(i==j)?0:Max;}return this.vertexlist.length()-1;}public void insertEdge(int i,int j,int weight){int n=this.vertexCount();if(i>=0&&i<n&&j>=0&&i!=j&&this.adjmatrix[i][j]==Max) this.adjmatrix[i][j]=weight;}public void insertEdge(Edge edge){this.insertEdge(edge.start,edge.dest,edge.weight);}}创建无向网邻接矩阵算法:public class MatrixGraph<T> {protected SeqList<T> vertexlist;protected int[][] adjmatrix;private final int Max=99999;public MatrixGraph(int size){size=size<10?10:size;this.vertexlist=new SeqList<T>(size);this.adjmatrix=new int[size][size];for(int i=0;i<size;i++)for(int j=0;j<size;j++)this.adjmatrix[i][j]=(i==j)?0:Max;}public MatrixGraph(T[] vertices,Edge[] edges){this(vertices.length);if(vertices==null)return;for(int i=0;i<vertices.length;i++)insertVertex(vertices[i]);if(edges!=null)for(int j=0;j<edges.length;j++)insertEdge(edges[j]);}public int vertexCount(){return this.vertexlist.length();public T get(int i){return this.vertexlist.get(i);}public int getWeight(int i,int j){return this.adjmatrix[i][j];}public String toString(){String str="顶点集合:"+this.vertexlist.toString()+"\n 邻接矩阵:\n";int n=this.vertexCount();for(int i=0;i<n;i++){for(int j=0;j<n;j++)str+=this.adjmatrix[i][j]==Max?" ∞":" "+this.adjmatrix[i][j];str+="\n";}return str;}public int insertVertex(T x){this.vertexlist.append(x);if(this.vertexCount()>this.adjmatrix.length){int temp[][]=adjmatrix,i,j;this.adjmatrix=new int[temp.length*2][temp.length^2];for(i=0;i<temp.length;i++){for(j=0;j<temp.length;j++)this.adjmatrix[i][j]=temp[i][j];for(j=temp.length;j<temp.length*2;i++)this.adjmatrix[i][j]=Max;}for(i=temp.length;i<temp.length*2;i++)for(j=0;j<temp.length*2;j++)this.adjmatrix[i][j]=(i==j)?0:Max;}return this.vertexlist.length()-1;}public void insertEdge(int i,int j,int weight){int n=this.vertexCount();if(i>=0&&i<n&&j>=0&&i!=j&&this.adjmatrix[i][j]==Max)this.adjmatrix[i][j]=weight;}public void insertEdge(Edge edge){this.insertEdge(edge.start,edge.dest,edge.weight);}}创建有向图邻接矩阵算法:(可使用前无向图邻接矩阵算法)创建有向网邻接矩阵算法:(可使用前无向图邻接矩阵算法)(3)输出邻接矩阵结果算法public static void main(String[] args){String[] vertices={"A","B","C","D","E"};Edge edges[]={new Edge(0,1,1),new Edge(0,3,1),new Edge(1,0,1),new Edge(1,2,1),new Edge(1,3,1),new Edge(2,1,1),new Edge(2,3,1),new Edge(2,4,1),new Edge(3,0,1),new Edge(3,1,1),new Edge(3,2,1),new Edge(3,4,1),new Edge(4,2,1),new Edge(4,3,1),};MatrixGraph<String> graph=new MatrixGraph<String>(vertices,edges);System.out.println("无向图:"+graph.toString());}public static void main(String[] args){String[] vertices={"A","B","C","D","E"};Edge edges[]={new Edge(0,1,5),new Edge(0,3,2),new Edge(1,0,5),new Edge(1,2,7),new Edge(1,3,6),new Edge(2,1,7),new Edge(2,3,8),new Edge(2,4,3),new Edge(3,0,2),new Edge(3,1,6),new Edge(3,2,8),new Edge(3,4,9),new Edge(4,2,3),new Edge(4,3,9)};MatrixGraph<String> graph=new MatrixGraph<String>(vertices,edges);System.out.println("无向网:"+graph.toString());}public static void main(String[] args){String[] vertices={"A","B","C","D","E"};Edge edges[]={new Edge(0,1,1),new Edge(0,3,1),new Edge(1,3,1),new Edge(2,3,1),new Edge(2,4,1),new Edge(3,1,1),new Edge(3,2,1),new Edge(4,2,1),new Edge(4,3,1)};MatrixGraph<String> graph=new MatrixGraph<String>(vertices,edges);System.out.println("有向图:"+graph.toString());}public static void main(String[] args){String[] vertices={"A","B","C","D","E"};Edge edges[]={new Edge(0,1,5),new Edge(0,3,2),new Edge(1,3,6),new Edge(2,3,8),new Edge(2,4,3),new Edge(3,1,9),new Edge(3,2,2),new Edge(4,2,3),new Edge(4,3,9)};MatrixGraph<String> graph=new MatrixGraph<String>(vertices,edges);System.out.println("有向网:"+graph.toString());}测试结果粘贴如下:2、图邻接表存储结构表示及基本操作算法实现(1)邻接表存储结构类定义:自定义如下:public class Vertex<T> {public T data;public SortedSinglyLinkedList<Edge> adjlink;public Vertex(T data){this.data=data;this.adjlink=new SortedSinglyLinkedList<Edge>();}public String toString(){return"\n"+this.data.toString()+": "+this.adjlink.toString();}}(2)创建邻接表算法创建无向网邻接表算法:(可使用下有向网邻接表算法)创建有向网邻接表算法:public class AdjListGraph<T> {protected SeqList<Vertex<T>> vertexlist;public AdjListGraph(int size){size=size<10?10:size;this.vertexlist=new SeqList<Vertex<T>>(size);}public AdjListGraph(T[] vertices,Edge[] edges){this(vertices.length*2);if(vertices==null)return;for(int i=0;i<vertices.length;i++)insertVertex(vertices[i]);if(edges!=null)for(int j=0;j<edges.length;j++)insertEdge(edges[j]);}public String toString(){return"出边表: \n"+this.vertexlist.toString()+"\n";}public int insertVertex(T x){this.vertexlist.append(new Vertex<T>(x));return this.vertexlist.length()-1;}public int vertexCount(){return this.vertexlist.length();}public void insertEdge(int i,int j,int weight){if(i>=0&&i<vertexCount()&&j>=0&&j<vertexCount()&&i!=j){Edge edge=new Edge(i,j,weight);SortedSinglyLinkedList<Edge>adjlink=this.vertexlist.get(i).adjlink;Node<Edge> front=adjlink.head,p=front.next;while(p!=null&&pareTo(edge)<0){front=p;p=p.next;}if(p!=null&&pareTo(edge)==0)return;front.next=new Node<Edge>(edge,p);}}public void insertEdge(Edge edge){this.insertEdge(edge.start,edge.dest,edge.weight);}(3)输出邻接表结果算法public static void main(String[] args){String[] vertices={"A","B","C","D","E"};Edge edges[]={new Edge(0,1,5),new Edge(0,3,2),new Edge(1,0,5),new Edge(3,0,2),new Edge(2,4,3),new Edge(4,2,3)};AdjListGraph<String> graph=new AdjListGraph<String>(vertices,edges);System.out.println("无向网:"+graph.toString());}public static void main(String[] args){String[] vertices={"A","B","C","D","E"};Edge edges[]={new Edge(0,1,5),new Edge(0,3,2),new Edge(1,0,6),new Edge(1,2,7),new Edge(2,4,3),new Edge(3,2,8),new Edge(3,4,9)};AdjListGraph<String> graph=new AdjListGraph<String>(vertices,edges);System.out.println("有向网:"+graph.toString());}测试结果粘贴如下:3、图的遍历递归算法(1)(存储结构为邻接表)深度优先遍历算法递归算法:public interface QQueue<T> {boolean isEmply();void enqueue(T x);T dequeue();}public class SeqQueue<T> implements QQueue<T>{private Object element[];private int front,rear;public SeqQueue(int length){if(length<64)length=64;this.element=new Object[Math.abs(length)];this.front=this.rear=0;}public SeqQueue(){this(64);}public boolean isEmply(){return this.front==this.rear;}public void enqueue(T x){if(x==null)return;if(this.front==(this.rear+1)%this.element.length){ Object[] temp = this.element;this.element=new Object[temp.length*2];int i=this.front,j=0;while(i!=this.rear){this.element[j]=temp[i];i=(i+1)%temp.length;j++;}this.front=0;this.rear=j;}this.element[this.rear]=x;this.rear=(this.rear+1)%this.element.length;}public T dequeue(){if(isEmply())return null;T temp=(T)this.element[this.front];this.front=(this.front+1)%this.element.length;return temp;}public String toString(){String str="(";if(!isEmply()){str+=this.element[this.front].toString();int i=(this.front+1)%this.element.length;while(i!=this.rear){str+=","+this.element[i].toString();i=(i+1)%this.element.length;}}return str+=")";}public int length(){return(this.element.length+this.rear-this.front)%(this.element.length);}}public abstract class AbstractGraph<T> {public abstract int vertexCount();public abstract T get(int i);public abstract int getNextNeighbor(int i,int j);public void DFSTraverse(int i){boolean[] visited= new boolean[this.vertexCount()];int j=i;do{if(!visited[j]){System.out.print("{");this.depthfs(j,visited);System.out.print("}");}j=(j+1)%this.vertexCount();}while(j!=i);System.out.println();}public void depthfs(int i,boolean[] visited){System.out.print(this.get(i)+" ");visited[i]=true;int j=this.getNextNeighbor(i, -1);while(j!=-1){if(!visited[j])depthfs(j,visited);j=this.getNextNeighbor(i, j);}}}public class AdjListGraph<T> extends AbstractGraph<T>{ protected SeqList<Vertex<T>> vertexlist;public AdjListGraph(int size){size=size<10?10:size;this.vertexlist=new SeqList<Vertex<T>>(size);}public T get(int i){return this.vertexlist.get(i).data;}public AdjListGraph(T[] vertices,Edge[] edges){this(vertices.length*2);if(vertices==null)return;for(int i=0;i<vertices.length;i++)insertVertex(vertices[i]);if(edges!=null)for(int j=0;j<edges.length;j++)insertEdge(edges[j]);}public String toString(){return"出边表: \n"+this.vertexlist.toString()+"\n";}public int insertVertex(T x){this.vertexlist.append(new Vertex<T>(x));return this.vertexlist.length()-1;}public int vertexCount(){return this.vertexlist.length();}public void insertEdge(int i,int j,int weight){if(i>=0&&i<vertexCount()&&j>=0&&j<vertexCount()&&i!=j){ Edge edge=new Edge(i,j,weight);SortedSinglyLinkedList<Edge>adjlink=this.vertexlist.get(i).adjlink;Node<Edge> front=adjlink.head,p=front.next;while(p!=null&&pareTo(edge)<0){front=p;p=p.next;}if(p!=null&&pareTo(edge)==0)return;front.next=new Node<Edge>(edge,p);}}public void insertEdge(Edge edge){this.insertEdge(edge.start,edge.dest,edge.weight);}public int getNextNeighbor(int i,int j){int n=this.vertexCount();if(i>=0&&i<n&&j>=-1&&j<n&&i!=j){Node<Edge> p=this.vertexlist.get(i).adjlink.head.next;while(p!=null){if(p.data.dest>j)return p.data.dest;p=p.next;}}return -1;}public static void main(String[] args){String[] vertices={"A","B","C","D","E"};Edge edges[]={new Edge(0,1,1),new Edge(0,3,1),new Edge(1,0,1),new Edge(1,2,1),new Edge(1,3,1),new Edge(3,0,1),new Edge(3,1,1),new Edge(3,2,1),newEdge(3,4,1),new Edge(2,3,1),new Edge(2,1,1),new Edge(2,4,1),new Edge(4,2,1),new Edge(4,3,1)};AdjListGraph<String> graph=new AdjListGraph<String>(vertices,edges);System.out.println(graph.toString());for(int i=0;i<graph.vertexCount();i++){graph.DFSTraverse(i);}}}public static void main(String[] args){String[] vertices={"A","B","C","D","E"};Edge edges[]={new Edge(0,1,1),new Edge(0,3,1),new Edge(1,0,1),new Edge(1,2,1),new Edge(3,2,1),new Edge(3,4,1),new Edge(2,4,1),};AdjListGraph<String> graph=new AdjListGraph<String>(vertices,edges);System.out.println(graph.toString());for(int i=0;i<graph.vertexCount();i++){graph.DFSTraverse(i);}}测试结果粘贴如下:有向网的测试结果:无向网的测试结果:(2)广度优先遍历算法非递归算法public abstract class AbstractGraph<T> {public abstract int vertexCount();public abstract T get(int i);public abstract int getNextNeighbor(int i,int j);public void BFSTraverse(int i){boolean[] visited=new boolean[this.vertexCount()];int j=i;do{if(!visited[j]){System.out.print("{");breadthfs(j,visited);System.out.print("}");}j=(j+1)%this.vertexCount();}while(j!=i);System.out.println();}public void breadthfs(int i,boolean[] visited){System.out.print(this.get(i)+" ");visited[i]=true;SeqQueue<Integer> que=new SeqQueue<Integer>(this.vertexCount());que.enqueue(new Integer(i));while(!que.isEmply()){i=que.dequeue().intValue();int j=this.getNextNeighbor(i, -1);while(j!=-1){if(!visited[j]){System.out.print(this.get(j)+"");visited[j]=true;que.enqueue(new Integer(j));}j=this.getNextNeighbor(i, j);}}}}public static void main(String[] args){String[] vertices={"A","B","C","D","E"};Edge edges[]={new Edge(0,1,1),new Edge(0,3,1),new Edge(1,0,1),new Edge(1,2,1),new Edge(3,2,1),new Edge(3,4,1),new Edge(2,4,1),};AdjListGraph<String> graph=new AdjListGraph<String>(vertices,edges);System.out.println(graph.toString());for(int i=0;i<graph.vertexCount();i++){graph.BFSTraverse(i);}}public static void main(String[] args){String[] vertices={"A","B","C","D","E"};Edge edges[]={new Edge(0,1,1),new Edge(0,3,1),new Edge(1,0,1),new Edge(1,2,1),new Edge(1,3,1),new Edge(3,0,1),new Edge(3,1,1),new Edge(3,2,1),newEdge(3,4,1),new Edge(2,3,1),new Edge(2,1,1),new Edge(2,4,1),new Edge(4,2,1),new Edge(4,3,1)};AdjListGraph<String> graph=new AdjListGraph<String>(vertices,edges);System.out.println(graph.toString());for(int i=0;i<graph.vertexCount();i++){graph.BFSTraverse(i);}}测试结果粘贴如下:有向网的测试结果:无向网的测试结果:三、实验心得(含上机中所遇问题的解决办法,所使用到的编程技巧、创新点及编程的心得)图这一章牵涉很广,仅是上三道题,就需要线性表、单链表、队列三种存储方式。

数据结构实验六图

数据结构实验六图

实验六图的表示与遍历一、实验目的1、掌握图的邻接矩阵和邻接表表示2、掌握图的深度优先和广度优先搜索方法3、理解图的应用方法二、实验内容和要求1、阅读并运行下面程序,根据输入写出运行结果。

#include<stdio.h>#define N 20#define TRUE 1#define FALSE 0int visited[N];typedef struct /*队列的定义*/{int data[N];int front,rear;}queue;typedef struct /*图的邻接矩阵*/{int vexnum,arcnum;char vexs[N];int arcs[N][N];}graph;void createGraph(graph *g); /*建立一个无向图的邻接矩阵*/ void dfs(int i,graph *g); /*从第i个顶点出发深度优先搜索*/ void tdfs(graph *g); /*深度优先搜索整个图*/void bfs(int k,graph *g); /*从第k个顶点广度优先搜索*/ void tbfs(graph *g); /*广度优先搜索整个图*/void init_visit(); /*初始化访问标识数组*/void createGraph(graph *g) /*建立一个无向图的邻接矩阵*/ { int i,j;char v;g->vexnum=0;g->arcnum=0;i=0;printf("输入顶点序列(以#结束):\n");while((v=getchar())!='#'){g->vexs[i]=v; /*读入顶点信息*/i++;}g->vexnum=i; /*顶点数目*/for(i=0;i<g->vexnum;i++) /*邻接矩阵初始化*/for(j=0;j<g->vexnum;j++)g->arcs[i][j]=0;printf("输入边的信息:\n");scanf("%d,%d",&i,&j); /*读入边i,j*/while(i!=-1) /*读入i,j为-1时结束*/{g->arcs[i][j]=1;g->arcs[j][i]=1;scanf("%d,%d",&i,&j);}}void dfs(int i,graph *g) /*从第i个顶点出发深度优先搜索*/ {int j;printf("%c",g->vexs[i]);visited[i]=TRUE;for(j=0;j<g->vexnum;j++)if((g->arcs[i][j]==1)&&(!visited[j]))dfs(j,g);}void tdfs(graph *g) /*深度优先搜索整个图*/{int i;printf("\n从顶点%C开始深度优先搜索序列:",g->vexs[0]); for(i=0;i<g->vexnum;i++)if(visited[i]!=TRUE)dfs(i,g);}void bfs(int k,graph *g) /*从第k个顶点广度优先搜索*/{int i,j;queue qlist,*q;q=&qlist;q->rear=0;q->front=0;printf("%c",g->vexs[k]);visited[k]=TRUE;q->data[q->rear]=k;q->rear=(q->rear+1)%N;while(q->rear!=q->front){i=q->data[q->front];q->front=(q->front+1)%N;for(j=0;j<g->vexnum;j++)if((g->arcs[i][j]==1)&&(!visited[j])){printf("%c",g->vexs[j]);visited[j]=TRUE;q->data[q->rear]=j;q->rear=(q->rear+1)%N;}}}void tbfs(graph *g) /*广度优先搜索整个图*/{int i;printf("\n从顶点%C开始广度优先搜索序列:",g->vexs[0]); for(i=0;i<g->vexnum;i++)if(visited[i]!=TRUE)bfs(i,g);}void init_visit() /*初始化访问标识数组*/{int i;for(i=0;i<N;i++)visited[i]=FALSE;}int main(){graph ga;int i,j;createGraph(&ga);printf("无向图的邻接矩阵:\n");for(i=0;i<ga.vexnum;i++){for(j=0;j<ga.vexnum;j++)printf("%3d",ga.arcs[i][j]);printf("\n");}init_visit();tdfs(&ga);init_visit();tbfs(&ga);return 0;}▪ 根据右图的结构验证实验,输入:ABCDEFGH#0,1 0,20,5 1,31,4 2,52,63,74,7-1,-1▪ 运行结果:2、阅读并运行下面程序,补充拓扑排序算法。

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

实验六图的应用及其实现一、实验目的1.进一步功固图常用的存储结构。

2.熟练掌握在图的邻接表实现图的基本操作。

3.理解掌握AOE网在邻接表上的实现及解决简单的应用问题。

二、实验内容[题目]:从键盘上输入AOE网的顶点和有向边的信息,建立其邻接表存储结构,输出其关键路径和关键路径长度。

试设计程序实现上述AOE网类型定义和基本操作,完成上述功能。

三、实验步骤(一)、数据结构与核心算法的设计描述本实验题目是基于图的基本操作以及邻接表的存储结构之上,着重拓扑排序算法的应用,做好本实验的关键在于理解拓扑排序算法的实质及其代码的实现。

(二)、函数调用及主函数设计以下是头文件中数据结构的设计和相关函数的声明:typedef struct ArcNode // 弧结点{int adjvex;struct ArcNode *nextarc;InfoType info;}ArcNode;typedef struct VNode //表头结点{VertexType vexdata;ArcNode *firstarc;}VNode,AdjList[MAX_VERTEX_NUM];typedef struct //图的定义{AdjList vertices;int vexnum,arcnum;int kind;}MGraph;typedef struct SqStack //栈的定义{SElemType *base;SElemType *top;int stacksize;}SqStack;int CreateGraph(MGraph &G);//AOE网的创建int CriticalPath(MGraph &G);//输出关键路径(三)、程序调试及运行结果分析(四)、实验总结在做本实验的过程中,拓扑排具体代码的实现起着很重要的作用,反复的调试和测试占据着实验大量的时间,每次对错误的修改都加深了对实验和具体算法的理解,自己的查错能力以及其他各方面的能力也都得到了很好的提高。

最终实验结果也符合实验的预期效果。

四、主要算法流程图及程序清单1、主要算法流程图:2、程序清单:创建AOE网模块:int CreateGraph(MGraph &G) //创建有向网{int i,j,k,Vi,Vj;ArcNode *p;cout<<"\n请输入顶点的数目、边的数目"<<endl;cin>>G.vexnum>>G.arcnum;for(i=0;i<G.vexnum;++i){ G.vertices[i].vexdata=i; G.vertices[i].firstarc=NULL;} for(k=0;k<G.arcnum;++k){cout<<"请输入第"<<k+1<<"条边的始点:"; cin>>Vi;cout<<"请输入第"<<k+1<<"条边的终点:"; cin>>Vj;i=Vi; j=Vj;i--; j--;p=(ArcNode *)malloc(sizeof(ArcNode));if(!p){ cout<<"Overflow!"; return (ERROR); }p->adjvex=j;p->nextarc=G.vertices[i].firstarc;p->info=NULL;G.vertices[i].firstarc=p;cout<<"请输入第"<<k+1<<"条边的权值:";cin>>p->info;}return (OK);}输出关键路径模块:int ve[MAX_VERTEX_NUM]; //存储事件的最早可能发生时间int vl[MAX_VERTEX_NUM]; //存储事件的最迟允许开始时间int InitStack(SqStack &S) //初始化栈{S.base=(SElemType *)malloc(STACK_INIT_SIZE*sizeof(SElemType)); if(!S.base){ cout<<"初始化栈失败!"; return(ERROR); }S.top=S.base;S.stacksize=STACK_INIT_SIZE;return(OK);}int Push(SqStack &S,SElemType e) //压栈{if(S.top-S.base>S.stacksize){S.base=(SElemType*)realloc(S.base,(S.stacksize+STACKINCREMENT *sizeof(SElemType)));if(!S.base){ cout<<endl<<"Overflow!"; return(ERROR); }S.top=S.base+S.stacksize;S.stacksize+=STACKINCREMENT;}*S.top++=e;return(OK);}int Pop(SqStack &S,SElemType &e) //弹出栈{if(S.top==S.base){cout<<"栈满 !"; return(ERROR); }e=*--S.top;return(OK);}int StackEmpty(SqStack S) //判断栈是否为空{if(S.top==S.base) return (YES);else return(NO);}void FindInDegree(MGraph G,int *indegree) //求各个顶点的入度{int i;for(i=0;i<G.vexnum;i++)indegree[i]=0;for(i=0;i<G.vexnum;i++)while(G.vertices[i].firstarc){indegree[G.vertices[i].firstarc->adjvex]++;G.vertices[i].firstarc=G.vertices[i].firstarc->nextarc;}}int TopologicalOrder(MGraph G,SqStack &T) //拓扑排序{int indegree[MAX_VERTEX_NUM];int i,count=0,j,k;ArcNode *p;SqStack S;FindInDegree(G,indegree);InitStack(S);for(i=0;i<G.vexnum;++i)if(!indegree[i]) Push(S,i); //入度为0的顶点入栈InitStack(T);for(i=0;i<=G.vexnum-1;i++) ve[i]=0;while(!StackEmpty(S)){Pop(S,j);Push(T,j); ++count;for(p=G.vertices[j].firstarc; p; p=p->nextarc){ k=p->adjvex;if(!(--indegree[k])) Push(S,k);if(ve[j]+p->info>ve[k]) ve[k]=ve[j]+p->info;}}if(count<G.vexnum) return(ERROR) ;else return(OK);}int CriticalPath(MGraph &G) //输出关键路径函数{int i,j,k,dut;int ee,el;char tag;ArcNode *p;SqStack T;if(!TopologicalOrder(G,T)) return(ERROR);for(i=0;i<=G.vexnum-1;i++)vl[i]=ve[G.vexnum-1];while(!StackEmpty(T)){for(Pop(T,j),p=G.vertices[j].firstarc; p; p=p->nextarc){k=p->adjvex;dut=p->info;if(vl[k]-dut<vl[j])vl[j]=vl[k]-dut;}}for(j=0;j<G.vexnum;++j)for(p=G.vertices[j].firstarc; p; p=p->nextarc){k=p->adjvex; dut=p->info;ee=ve[j]; el=vl[k]-dut;tag=(ee==el)?'*':' ';if(tag=='*')cout<<"V"<<j+1<<"->V"<<k+1<<" "<<"活动最早可能开始时间"<<ee<<" 最迟允许开始时间"<<el<<" "<<endl;}}。

相关文档
最新文档