以邻接矩阵方式确定有向网课程设计报告
实验报告:图
实验报告(实验七)专业班级姓名学号课程名称数据结构学年2009 --2010 学期1□/ 2□课程类别专业必修□限选□任选□实践□●实验内容:实验时间:2010年7月2日1.编写函数,采用邻接矩阵表示法,构造一个无向网。
2.编写函数,实现从键盘输入数据,建立一个有向图的邻接表。
3.编写函数,输出该邻接表。
4.编写函数,采用邻接表存储实现无向图的深度优先非递归遍历。
5.编写函数,采用邻接表存储实现无向图的广度优先遍历。
6.编写一个主函数,在主函数中设计一个简单的菜单,分别调试上述算法。
●实验目的及要求:1.掌握图的存储思想及其存储实现2.掌握图的深度、广度优先遍历算法思想及其程序实现3.掌握图的常见应用算法的思想及其程序实现●方法与步骤:详见从第2页开始的源代码●实验结果:●小结:分数:批阅老师:2010年月日实验报告(附页)源代码:#include<stdio.h>#include<stdlib.h>#include<string.h>#define MAX_VERTEX_NUM 10 //顶点最大个数#define STACK_INIT_SIZE 100//邻接矩阵的类型定义#define INFINITY 888 /* 用888代替∞*/typedef struct ArcCell{int adj;}ArcCell,AdjMatrix[MAX_VERTEX_NUM][MAX_VERTEX_NUM]; typedef struct{int vexs[MAX_VERTEX_NUM];AdjMatrix arcs;int vexnum,arcnum;}MGraph;//构造无向网MGraph *CreateUDN(MGraph *N){int i,j,k,w;int v1,v2;printf("输入顶点的个数:");scanf("%d",&N->vexnum);printf("输入边数:");scanf("%d",&N->arcnum);printf("输入%d个顶点的元素:",N->vexnum);for(i=0;i<N->vexnum;i++){scanf("%d",&N->vexs[i]);}for(i=0;i<N->vexnum;i++)for(j=0;j<N->vexnum;j++)N->arcs[i][j].adj=INFINITY;for(k=0;k<N->arcnum;k++){printf("输入第%d条边所依附的顶点:",k+1);scanf("%d%d",&v1,&v2);printf("输入权值:");scanf("%d",&w);for(i=0;i<N->vexnum;i++)if(v1==N->vexs[i])break;for(j=0;j<N->vexnum;j++)if(v2==N->vexs[j])break;N->arcs[i][j].adj=w;N->arcs[j][i]=N->arcs[i][j];}printf(" ");for(i=0;i<N->vexnum;i++)printf(" v%d",N->vexs[i]);printf("\n");for(i=0;i<N->vexnum;i++){printf(" v%d",N->vexs[i]);for(j=0;j<N->vexnum;j++)printf(" %3d ",N->arcs[i][j].adj);printf("\n");}return N;}//邻接表的类型定义typedef struct ArcNode{int adjvex;struct ArcNode *nextarc;int weight; //边的权}ArcNode; //表结点typedef struct VNode{int degree,indegree;//顶点的度,入度int data;ArcNode *firstarc;}VNode,AdjList[MAX_VERTEX_NUM];typedef struct{AdjList vertices;int vexnum,arcnum;//顶点的实际数,边的实际数}ALGraph;#define TRUE 0#define FALSE -1//确定位置int LocateVex(ALGraph *G,int v){int i;for( i=0;v!=G->vertices[i].data&&i<G->vexnum;++i);if(i>G->vexnum)return -1;return i;}//创建有向图的邻接表ALGraph *createDG(ALGraph *G){int i,j,k;int v1,v2;ArcNode *p;printf("输入顶点的个数:");scanf("%d",&G->vexnum);printf("输入边数:");scanf("%d",&G->arcnum);printf("输入%d个顶点的元素:",G->vexnum);for(i=0;i<G->vexnum;++i){scanf("%d",&G->vertices[i].data);G->vertices[i].firstarc=NULL;}for(k=0;k<G->arcnum;++k){printf("输入第%d条边所依附的顶点:",k+1);scanf("%d%d",&v1,&v2);i=LocateVex(G,v1);j=LocateVex(G,v2);p=(ArcNode *)malloc(sizeof(ArcNode));p->adjvex=j;p->nextarc=G->vertices[i].firstarc;G->vertices[i].firstarc=p;}printf("创建成功邻接表!\n");return G;}//输出邻接表void printfAdjList(ALGraph *G){int i;ArcNode *p;printf(" %s %s %s\n","编号","顶点","相邻边编号");for (i=0;i<G->vexnum;++i){printf("%4d v%d",i,G->vertices[i].data);for(p=G->vertices[i].firstarc;p;p=p->nextarc)printf("->%2d", p->adjvex);printf("\n");}}//顺序栈类型定义typedef struct{int *base;int *top;int stacksize;}SqStack;//栈初始化SqStack *InitStack(){SqStack *s;s=(SqStack *)malloc(sizeof(SqStack));s->base=(int *)malloc(STACK_INIT_SIZE*sizeof(int));s->top=s->base;s->stacksize=STACK_INIT_SIZE;return s;}//入栈SqStack *PushStack(SqStack *s,int i){(*s->top)=i;s->top++;return s;}//出栈int PopStack(SqStack *s){int i;if(s->top==s->base)return NULL;s->top--;i=(*s->top);return i;}//深度优先非递归遍历void DFSTraverse(ALGraph *G){int i,u;char visited[MAX_VERTEX_NUM]={0};SqStack *s;ArcNode *p;s=InitStack();for(i=0;i<G->vexnum;i++)visited[i]=FALSE;for(i=0;i<G->vexnum;i++)if(visited[i]){visited[i]=TRUE;printf("%d ",G->vertices[i].data);s=PushStack(s,i);while((s->base!=s->top)){u=PopStack(s);s=PushStack(s,u);for(p=G->vertices[u].firstarc;p;p=p->nextarc){if(visited[p->adjvex]){visited[p->adjvex]=TRUE;printf("%d ",G->vertices[p->adjvex].data);s=PushStack(s,p->adjvex);break;}else{u=PopStack(s);}}}}}//创建无向图的邻接表ALGraph *createUDG(ALGraph *G){int i,j,k;int v1,v2;ArcNode *p,*q;printf("输入顶点的个数:");scanf("%d",&G->vexnum);printf("输入边数:");scanf("%d",&G->arcnum);printf("输入%d个顶点的元素:",G->vexnum);for(i=0;i<G->vexnum;++i){scanf("%d",&G->vertices[i].data);G->vertices[i].firstarc=NULL;}for(k=0;k<G->arcnum;++k){printf("输入第%d条边所依附的顶点:",k+1);scanf("%d%d",&v1,&v2);i=LocateVex(G,v1);j=LocateVex(G,v2);p=(ArcNode *)malloc(sizeof(ArcNode));p->adjvex=j;p->nextarc=G->vertices[i].firstarc;G->vertices[i].firstarc=p;q=(ArcNode *)malloc(sizeof(ArcNode));q->adjvex=i;q->nextarc=G->vertices[j].firstarc;G->vertices[j].firstarc=q;}printf("创建成功邻接表!\n");return G;}//单链队列的类型定义typedef struct QNode{int data;struct QNode *next;}QNode,*QueuePtr;typedef struct{QueuePtr front;//队头指针QueuePtr rear;//队尾指针}*LinkQueue,Queue;//创建队列LinkQueue InitLinkQueue(){LinkQueue Q;Q=(LinkQueue)malloc(sizeof(Queue));Q->front=Q->rear=(QueuePtr)malloc(sizeof(QNode));Q->front->next=NULL;return Q;}//入队LinkQueue EnLinkQueue(LinkQueue Q,int data){QueuePtr p;p=(QueuePtr)malloc(sizeof(QNode));p->data=data;p->next=NULL;Q->rear->next=p;Q->rear=p;return Q;}//出队int DeLinkQueue(LinkQueue Q){QueuePtr p;int data;p=Q->front->next;data=p->data;Q->front->next=p->next;if(Q->rear==p)Q->rear=Q->front;free(p);return data;}//广度优先遍历void BFSTraverse(ALGraph *G){LinkQueue Q;ArcNode *p;int i,u;char visited[MAX_VERTEX_NUM];Q=InitLinkQueue();for(i=0;i<G->vexnum;i++)visited[i]=FALSE;for(i=0;i<G->vexnum;i++)if(visited[i]){visited[i]=TRUE;printf("%d ",G->vertices[i].data);Q=EnLinkQueue(Q,i);while(Q->front!=Q->rear){u=DeLinkQueue(Q);for(p=G->vertices[u].firstarc;p;p=p->nextarc){if(visited[p->adjvex]){visited[p->adjvex]=TRUE;printf("%d ",G->vertices[p->adjvex].data);Q=EnLinkQueue(Q,p->adjvex);}}}}}//主函数void main(){int choice;MGraph *N;ALGraph *G;N=(MGraph *)malloc(sizeof(MGraph));G=(ALGraph *)malloc(sizeof(ALGraph));do{ printf("\t\t************************************************\n");printf("\t\t*1.采用邻接矩阵表示法,构造一个无向网*\n");printf("\t\t*2.实现从键盘输入数据,建立一个有向图的邻接表*\n");printf("\t\t*3.输出2中建立的有向图的邻接表*\n");printf("\t\t*4.构造一个无向图*\n");printf("\t\t*5.采用邻接表存储实现无向图的深度优先非递归遍历*\n");printf("\t\t*6.采用邻接表存储实现无向图的广度优先遍历*\n");printf("\t\t*0:退出*\n");printf("\t\t*请选择:0-6 *\n");printf("\t\t************************************************\n");scanf("%d",&choice);switch(choice){case 1:CreateUDN(N);break;case 2:G=createDG(G);break;case 3:printfAdjList(G);break;case 4:G=createUDG(G);break;case 5:DFSTraverse(G);printf("\n");break;case 6:BFSTraverse(G);printf("\n");break;}}while(choice!=0);}程序调试截图:主菜单:采用邻接矩阵表示法,构造一个无向网:实现从键盘输入数据,建立一个有向图的邻接表:输出2中建立的有向图的邻接表:构造一个无向图:采用邻接表存储实现无向图的深度优先非递归遍历:采用邻接表存储实现无向图的广度优先遍历:。
邻接矩阵创建有向网的实现
}AMGraph;
Status LocateVex(AMGraph G,char v)
{
int i;
for(i=0; i<G.vexnum; i++)
if(G.vexs[i]==v)
return i;
return ERROR;
}
Status CreateDN(AMGraph& G)
typedef char VerTexType;//假设顶点的数据类型为字符型
typedef int ArcType;//假设边的权值类型为整型
typedef int Status;
typedef struct
{
VerTexType vexs[MVNum];//顶点表
ArcType arcs[MVNum][MVNum];//邻接矩阵
{
cout<<"请输入总顶点数和总边数:"<<endl;
cin>>G.vexnum>>G.arcnum;//输入总定点数,总边数
cout<<"次输入点的信息:"<<endl;
for(int i=0;i<G.vexnum;i++)/依次输入点的信息
cin>>G.vexs[i];
for(int i=0;i<G.vexnum;i++)//初始化邻接矩阵,边的权值均置为极大值MaxInt
for(i=0;i<G.vexnum;i++)
{
for(j=0;j<G.vexnum;j++)
算法与数据结构课设(有向图,无向图,有向网,无向网)
算法与数据结构课程设计报告系(院):计算机科学学院专业班级:教技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(权值)。
数据结构课程设计-图的邻接矩阵
数据结构课程设计报告设计题目:图的邻接矩阵存储结构院系计算机学院年级x 级学生xxxx学号xxxxxxxxxx指导教师xxxxxxxxx起止时间10-6/10-102013年10月10日目录1 需求分析 (3)2 概要设计 (4)2.1 ADT描述 (4)2.2程序模块结构 (5)2.3各功能模块 (6)3详细设计 (7)3.1类的定义 (7)3.2 初始化 (8)3.3 图的构建操作 (8)3.4 输出操作 (9)3.5 get操作 (9)3.6 插入操作 (10)3.7 删除操作 (10)3.8 求顶点的度操作 (11)3.10 判断连通操作 (12)3.11 主函数 (13)4 调试分析 (16)4.1调试问题 (16)4.2 算法时间复杂度 (16)5用户手册 (16)5.1 主界面 (16)5.2 创建图 (17)5.3插入节点 (17)5.4 深度优先遍历 (17)5.5 求各顶点的度 (18)5.6 输出图 (18)5.7 判断是否连通 (19)5.8 求边的权值 (19)5.9 插入边 (19)5.10 删除边 (20)结论 (20)参考文献 (20)摘要随着计算机的普及,涉及计算机相关的科目也越来越普遍,其中数据结构是计算机专业重要的专业基础课程与核心课程之一,为适应我国计算机科学技术的发展和应用,学好数据结构非常必要,然而要掌握数据结构的知识非常难,所以对“数据结构”的课程设计比不可少。
本说明书是对“无向图的邻接矩阵存储结构”课程设计的说明。
首先是对需求分析的简要阐述,说明系统要完成的任务和相应的分析,并给出测试数据。
其次是概要设计,说明所有抽象数据类型的定义、主程序的流程以及各程序模块之间的层次关系,以及ADT描述。
然后是详细设计,描述实现概要设计中定义的基本功操作和所有数据类型,以及函数的功能及代码实现。
再次是对系统的调试分析说明,以及遇到的问题和解决问题的方法。
然后是用户使用说明书的阐述,然后是测试的数据和结果的分析,最后是对本次课程设计的结论。
数据结构与算法课程设计报告---图的算法实现
数据结构与算法课程设计报告课程设计题目:图的算法实现专业班级:信息与计算科学1002班目录摘要 (1)1、引言 (1)2、需求分析 (1)3、概要设计 (2)4、详细设计 (4)5、程序设计 (10)6、运行结果 (18)7、总结体会 (19)摘要(题目): 图的算法实现实验内容图的算法实现问题描述:(1)将图的信息建立文件;(2)从文件读入图的信息,建立邻接矩阵和邻接表;(3)实现Prim、Kruskal、Dijkstra和拓扑排序算法。
关键字:邻接矩阵、Dijkstra和拓扑排序算法1.引言本次数据结构课程设计共完成图的存储结构的建立、Prim、Kruskal、Dijkstra 和拓扑排序算法等问题。
通过本次课程设计,可以巩固和加深对数据结构的理解,通过上机和程序调试,加深对课本知识的理解和熟练实践操作。
(1)通过本课程的学习,能够熟练掌握数据结构中图的几种基本操作;(2)能针对给定题目,选择相应的数据结构,分析并设计算法,进而给出问题的正确求解过程并编写代码实现。
使用语言:CPrim算法思想:从连通网N={V,E}中的某一顶点v0出发,选择与它关联的具有最小权值的边(v0,v),将其顶点加入到生成树的顶点集合V中。
以后每一步从一个顶点在V中,而另一个顶点不在V中的各条边中选择权值最小的边(u,v),把它的顶点加入到集合V中。
如此继续下去,直到网中的所有顶点都加入到生成树顶点集合V中为止。
拓扑排序算法思想:1、从有向图中选取一个没有前驱的顶点,并输出之;2、从有向图中删去此顶点以及所有以它为尾的弧;重复上述两步,直至图空,或者图不空但找不到无前驱的顶点为止。
没有前驱-- 入度为零,删除顶点及以它为尾的弧-- 弧头顶点的入度减1。
2.需求分析1、通过键盘输入建立一个新的有向带权图,建立相应的文件;2、对建立的有向带权图进行处理,要求具有如下功能:(1)用邻接矩阵和邻接表的存储结构输出该有向带权图,并生成相应的输出结果;(2)用Prim、Kruskal算法实现对图的最小生成树的求解,并输出相应的输出结果;(3)用Dijkstra算法实现对图中从某个源点到其余各顶点的最短路径的求解,并输出相应的输出结果;(4)实现该图的拓扑排序算法。
关键路径中的邻接矩阵
关键路径中的邻接矩阵1.引言1.1 概述在撰写关于关键路径中的邻接矩阵的长文之前,我们需要先了解一些基本概念。
关键路径是指项目中影响整体工期的关键任务序列,而邻接矩阵则是一种常用的图表示方法。
本文中,我们将详细讨论关键路径中的邻接矩阵的应用和意义。
在正文部分,我们将对关键路径和邻接矩阵进行详细的介绍和解释。
通过对关键路径的定义和意义的说明,我们能够更好地理解为什么需要使用邻接矩阵来分析关键路径。
在正文的第二部分,我们将介绍邻接矩阵的基本知识和原理。
邻接矩阵是一种用于表示图结构的数据结构,通过将图的节点和边映射为矩阵中的元素,我们能够方便地进行图的分析和计算。
最后,在结论部分,我们将探讨关键路径中的邻接矩阵的应用。
通过使用邻接矩阵,我们可以有效地确定项目关键路径,并对项目的工期进行准确的估计和优化。
总结部分将回顾本文所介绍的关键内容,并对关键路径中的邻接矩阵的应用进行总结和展望。
通过本文的撰写和阅读,我们将能够更全面地了解关键路径中的邻接矩阵的概念、原理和应用。
希望本文能够为读者提供有关关键路径分析和邻接矩阵应用的深入理解,并对相关领域的研究和实践有所启发。
1.2 文章结构文章结构部分的内容可以如下所示:本文的结构主要分为引言、正文和结论三个部分。
在引言部分,我们将对本文进行概述,介绍关键路径中的邻接矩阵的相关概念和背景,并说明本文的目的。
通过引言,读者可以对本文的内容有一个整体的认识和了解。
在正文部分,我们将分为两个小节进行阐述。
首先,在2.1小节中,我们将详细介绍关键路径的定义和意义。
关键路径是项目管理中非常重要的概念,它能够帮助项目管理者合理规划项目进度和资源,以实现项目目标。
我们将从关键路径的定义、计算方法以及其在项目管理中的意义等方面进行阐述,使读者对关键路径有一个深入的理解。
接着,在2.2小节中,我们将详细介绍邻接矩阵的概念和应用。
邻接矩阵是图论中用于表示图的数据结构,它能够清晰地描述各个节点之间的关系。
《数据结构》课程设计报告-目录及正文
目录1 前言 (1)2 需求分析 (1)2.1课程设计目的 (2)2.2课程设计任务 (2)2.3设计环境 (2)3 概要设计 (2)3.1数据结构设计 (2)3.2模块设计 (6)4 详细设计 (10)5 测试分析 (26)6 课程设计总结 (29)参考文献 (30)致谢 (30)1 前言在交通网络非常发达的今天,人们出差、旅游或做其他出行时,不仅关心节省交通费用,而且对里程和所需时间等问题也很感兴趣。
对于这样一个人们关心的问题,可用一个图结构来表示交通网络系统,利用计算机建立一个交通指南系统。
图中顶点表示城市,边表示城市之间的交通关系。
设计一个交通指南系统,能让旅客咨询从任一个城市顶点到达另外一个城市顶点之间的最短路径(里程)的问题.2 需求分析2.1课程设计目的本实验的核心代码是用FLOYD算法求有向网G中各对顶点v和w之间的最短路径P[v][w]及其带权长度D[v][w],其中利用到了一些稍许繁琐的数据存储结,求解最优路线问题解决相关实际问题,得到软件设计技能训练。
2.2课程设计任务假设以一个带权有向图表示某一区域的公交线路网,图中顶点代表一些区域中的重要场所,弧代表已有的公交线路,弧上的权表示该线路上的票价(或搭乘所需时间),试设计一个交通指南系统,指导前来咨询者以最低的票价或最少的时间从区域中的某一场所到达另一场所。
2.3设计环境(1)WINDOWS 2000/2003/XP/7/Vista系统(2)Visual C++或TC集成开发环境3 概要设计3.1数据结构设计结点类型:struct ArcCell{int adj; //存放弧长bool *info; //是否用过该弧};struct _MGraph{char vexs[20]; //存放站点ArcCell arcs[20][20]; //<i,j>int vexnum;int arcnum;};类定义:class MGraph //没用私有成员{public:_MGraph mgraph;//void DestroyGraph(); //析构函数销毁图int LocateVex (char u); // 返回顶点在图中的位置bool CreateDN(); //构造有向网void ShortestPath_FLOYD(Path &P,Distanc &D);};}3.2模块设计3.21构造有向网bool MGraph::CreateDN()//构造有向网{int i,j ,w;char v1, v2;cout<<"请输入站点个数,直接线路的条数: ";cin>>mgraph.vexnum>>mgraph.arcnum ;cout<<"\n请输入各站点名: ";for(i = 0;i<mgraph.vexnum;i++)//构造顶点向量{cin>>mgraph.vexs[i];}for(i = 0;i<mgraph.vexnum;i++) //初始化邻接矩阵{for(j = 0;j<mgraph.vexnum;j++){if(i==j)mgraph.arcs[i][j].adj = 0;elsemgraph.arcs[i][j].adj = 20000; //infinity;mgraph.arcs[i][j].info = false;}}for(i = 0;i<mgraph.arcnum;i++) //构造邻接矩阵{cout<<"\n请输入一条线路的起点,终点,距离(公里): ";cin>>v1>>v2>>w;int m = LocateVex(v1);int n = LocateVex(v2);mgraph.arcs[m][n].adj = w; // <v1, v2>的权值}return true;}3.22销毁有向图void MGraph::DestroyGraph(){for(int i = 0 ;i<mgraph.vexnum;i++)for(int j = 0;j<mgraph.vexnum;j++){if(mgraph.arcs[i][j].info){delete []mgraph.arcs[i][j].info;mgraph.arcs[i][j].info = false;}}mgraph.vexnum = 0;mgraph.arcnum = 0;}3.23定位点int MGraph::LocateVex(char u){for(int i = 0 ;i<20;i++){if(u == mgraph.vexs[i]){return i;}}return -1;}3.24最短路径void MGraph::ShortestPath_FLOYD(Path &P,Distanc &D)//求每对顶点间的最短路径// 用Floyd算法求有向网G中各对顶点v和w之间的最短路径P[v][w]及其带权长度D[v][w]// 若P[v][w][u]为TRUE,则u是从v到w当前求得最短路径上的顶点。
邻接矩阵课课程设计
邻接矩阵课课程设计一、教学目标本课程的教学目标是使学生掌握邻接矩阵的概念、性质及其在图论中的应用。
通过本课程的学习,学生应能够:1.知识目标:a.理解图的基本概念及其表示方法。
b.掌握邻接矩阵的定义、性质和计算方法。
c.了解邻接矩阵在图的遍历、最短路径等算法中的应用。
2.技能目标:a.能够熟练地运用邻接矩阵表示图。
b.能够运用邻接矩阵进行图的遍历和最短路径计算。
c.能够运用邻接矩阵解决一些简单的图论问题。
3.情感态度价值观目标:a.培养学生的逻辑思维能力和问题解决能力。
b.培养学生的团队合作意识和交流沟通能力。
c.培养学生的创新精神和自主学习能力。
二、教学内容本课程的教学内容主要包括以下几个部分:1.图的基本概念及其表示方法。
a.图的定义和基本术语。
b.图的邻接表和邻接矩阵表示方法。
2.邻接矩阵的定义、性质和计算方法。
a.邻接矩阵的定义和性质。
b.邻接矩阵的计算方法。
3.邻接矩阵在图的遍历、最短路径等算法中的应用。
a.邻接矩阵的图的遍历算法。
b.邻接矩阵的最短路径算法。
三、教学方法为了实现本课程的教学目标,我们将采用以下教学方法:1.讲授法:通过讲解图的基本概念、邻接矩阵的定义和性质等理论知识,使学生掌握相关概念和理论。
2.案例分析法:通过分析一些具体的图论问题,引导学生运用邻接矩阵解决问题,培养学生的问题解决能力。
3.实验法:通过上机实验,让学生亲手编写代码,运用邻接矩阵进行图的遍历和最短路径计算,提高学生的实际操作能力。
四、教学资源为了支持本课程的教学内容和教学方法的实施,我们将准备以下教学资源:1.教材:《图论及其应用》。
2.参考书:图论相关论文和教材。
3.多媒体资料:PPT课件、教学视频等。
4.实验设备:计算机、网络等。
五、教学评估为了全面、客观、公正地评估学生的学习成果,本课程将采用以下评估方式:1.平时表现:通过观察学生在课堂上的参与程度、提问回答、小组讨论等表现,评估学生的学习态度和理解能力。
数据结构课程设计报告-最短路径算法-二叉树的三种遍历
数据结构课程设计报告班级:计算机科学与技术132班姓名:赖恒财指导教师:董跃华成绩:32信息工程学院2015 年7月8日目录图的最短路径算法实现1. 需求分析 (1)1.1 程序设计内容 (1)1.2 设计要求 (1)2.概要设计 (2)3.详细设计 (2)3.1 数据类型的定义 (2)3.2 功能模块的设计 (2)3.3 主程序流程 (9)4.调试分析 (10)4.1 问题回顾和分析 (10)4.2.经验和体会 (11)5.测试结果 (12)二叉树的遍历1.设计目的 (13)2.需求分析 (14)2.1课程设计的内容和要求 (14)2.2选题的意义及背景 (14)3.概要设计 (14)3.1设计思想 (14)3.2程序数据类型 (16)3.3程序模块分析 (16)3.3.1置空栈 (16)3.3.2入栈 (17)3.3.3出栈 (17)3.3.4取栈顶操作 (17)3.3.5判空栈 (17)3.4函数关系: (18)4.详细设计 (18)4.1二叉树算法程序截图和结果 (18)5.程序测试结果及问题分析 (19)6.总结 (20)参考文献 (21)附录1 (22)附录2 (26)图的最短路径算法实现----基于floyd最短路径算法1.需求分析设计校园平面图,所含景点不少于8个。
以图中顶点表示学校内各景点,存放景点的名称、景点介绍信息等;以边表示路径,存放路径长度信息。
要求将这些信息保存在文件graph.txt中,系统执行时所处理的数据要对此文件分别进行读写操作。
1.1程序设计内容1.从文件graph.txt中读取相应数据, 创建一个图,使用邻接矩阵表示图;2.景点信息查询:为来访客人提供校园任意景点相关信息的介绍;3.问路查询:为来访客人提供校园任意两个景点之间的一条最短路径。
1.2 设计要求(1) 程序要具在一定的健壮性,即当输入数据非法时,程序也能适当地做出反应。
(2) 程序要添加适当的注释,程序的书写要采用缩进格式。
数据结构与算法课程实验报告-图的应用
(前面可加目录页)一. 实验目的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++)。
算法与数据结构课程设计(有向图,无向图,有向网,无向网)
算法与数据结构课程设计报告系(院):计算机科学学院专业班级:教技1001班*名:***学号:*********指导教师:***设计时间:2012.6.16 - 2012.6.24设计地点:4号楼2号机房目录一、设计方案及实现过程******************第3页二、实现代码***********************************第4页三、测试******************************************第19页四、难点与收获********************************第21页一、设计方案及实现过程这次课程设计要求实现无向图、有向图、无向网以及有向网的一些基本操作以及应用,大体的方案是先进入界面后,选择无向图、有向图、无向网、无向网中的一个,然后创建相应的图或者网,创建好后,在此基础上选择进行相关的操作,具体的函数放在main函数前面,通过多次函数调用已达到具体操作的实现。
流程图如下:进入选择界面1 无向图创建无向图1 创建无向图的邻接矩阵函数调用2 创建无向图的邻接表函数调用3无向图的深度优先遍历函数调用4 无向图的广度优先遍历函数调用5 返回选择主界面2 有向图3 无向网4 有向网5 退出有向图、无向网、有向网的操作和无向图类似,在这里不一一列举。
二、实现代码#include<stdio.h># include <stdlib.h># define maxlen 10# define large 999# define true 1# define false 0# define ok 1# define error 0# define overflow -2# define null 0typedef int status;#include <ctype.h>#include <string.h>#include <queue>#include <stack>#include <process.h>using namespace std;#define MAX_VERTEX_NUM 20#define MAX 1000typedef struct{int a[maxlen],b[maxlen],h[maxlen];char vexs[maxlen];int vexnum,arcnum;int kind;int arcs[maxlen][maxlen];}graph;typedef struct node{int adjvex;int info;struct node *next;}edgenode;typedef struct{int id;char data;edgenode *link;}vexnode;typedef struct{vexnode adjs[maxlen];int vexnum,arcnum;int kind;}adjlist;typedef struct qnode{int data;struct qnode *next;}linkqlist;typedef struct{linkqlist *front;linkqlist *rear;} linkqueue;typedef struct{int stack[maxlen];int top;}stackstru;int cnull=-1;graph g;adjlist adjl;stackstru *t;stackstru *s;linkqueue *q;graph printf_adjmatrix(graph g){int i,j;printf("邻接矩阵:\n");printf("vertex\t");for (i=0;i<g.vexnum;i++) printf("%4c",g.vexs[i]);printf("\n");for(i=0;i<g.vexnum;i++){printf("% 4c \t",g.vexs[i]);for(j=0;j<g.vexnum;j++) printf("%4d",g.arcs[i][j]);printf("\n");}return g;}void create_2(graph g){ //构造有向图int i,j,k,c=0;for (i=0;i<g.vexnum;i++)for(j=0;j<g.vexnum;j++)g.arcs[i][j]=c;for(k=0;k<g.arcnum;k++)g.arcs[g.a[k]-1][g.b[k]-1]=1;printf_adjmatrix(g);}void create_1(graph g){ //构造无向图int i,j,k,c=0;for (i=0;i<g.vexnum;i++)for(j=0;j<g.vexnum;j++)g.arcs[i][j]=c;for(k=0;k<g.arcnum;k++){g.arcs[g.a[k]-1][g.b[k]-1]=1;g.arcs[g.b[k]-1][g.a[k]-1]=1;}printf_adjmatrix(g);}graph create_4(graph g){ //构造有向网int i,j,k,c=999;for (i=0;i<g.vexnum;i++)for(j=0;j<g.vexnum;j++)g.arcs[i][j]=c;for(k=0;k<g.arcnum;k++)g.arcs[g.a[k]-1][g.b[k]-1]=g.h[k];printf_adjmatrix(g);return g;}graph create_3(graph g){ //构造无向网int i,j,k,c=999;for (i=0;i<g.vexnum;i++)for(j=0;j<g.vexnum;j++)g.arcs[i][j]=c;for (k=0;k<g.arcnum;k++){g.arcs[g.a[k]-1][g.b[k]-1]=g.h[k];g.arcs[g.b[k]-1][g.a[k]-1]=g.h[k];}printf_adjmatrix(g);return g;}void creategraph(graph g){switch(g.kind){case 1:create_1(g);break;case 2:create_2(g);break;case 3:create_3(g);break;case 4:create_4(g);break;default:printf("Error\n");}}adjlist createlist (graph g ,adjlist adjl){ //创建邻接表int i;edgenode *p;if(g.kind==1||g.kind==3){//创建有向邻接表for(i=0;i<adjl.arcnum;i++){p=(edgenode*)malloc(sizeof(edgenode));p->adjvex=g.b[i];p->info=g.h[i];p->next=adjl.adjs[g.a[i]-1].link;adjl.adjs[g.a[i]-1].link=p;}}if(g.kind==2||g.kind==4){//创建无向邻接表for(i=0;i<adjl.arcnum;i++){p=(edgenode*)malloc(sizeof(edgenode));p->info=g.h[i];p->adjvex=g.b[i];p->next=adjl.adjs[g.a[i]-1].link;adjl.adjs[g.a[i]-1].link=p;p=(edgenode*)malloc(sizeof(edgenode));p->info=g.h[i];p->adjvex=g.a[i];p->next=adjl.adjs[g.b[i]-1].link;adjl.adjs[g.b[i]-1].link=p;}}printf("邻接表为:\n");for(i=0;i<g.vexnum;i++){printf("[%d,%c]=>",i+1,adjl.adjs[i].data);p=adjl.adjs[i].link;while(p!=null){printf("[%c,%d]-->",adjl.adjs[(p->adjvex)-1].data,p->info);p=p->next;}printf("^\n");}return adjl;}void initqueue(linkqueue *p){ //构造空队列p->front=(linkqlist *)malloc(sizeof(linkqlist));p->rear=p->front;(p->front)->next=null;}status empty(linkqueue *q){ //判断是否为空int v;if(q->front==q->rear) v=true;else v=false;return v;}int addqueue(linkqueue *q,int e){q->rear->next=(linkqlist *)malloc(sizeof(linkqlist));q->rear=q->rear->next;if(!q->rear) return -1;q->rear->data=e;q->rear->next=null;return ok;}status delqueue(linkqueue *q){ //linkqlist *p;int e;if (q->front==q->rear)printf("the linklist is overflow");else p=(q->front)->next;(q->front)->next=p->next;e=p->data;if(q->rear==p)q->rear=q->front;free(p);return(e);}bool visit[maxlen]; //深度优先搜索void DFS(adjlist adjl,int i){edgenode *p;visit[i]=1;printf("%c ",adjl.adjs[i].data);for(p=adjl.adjs[i].link;p;p=p->next){if(!visit[p->adjvex]) DFS(adjl,p->adjvex);}}void DFSTraverse(adjlist adjl){int i;printf("\t\t深度优先搜索:");for( i=0;i<maxlen;i++)visit[i]=false;for( i=0;i<=adjl.vexnum;i++)if(!visit[i]) DFS(adjl,i);}queue <int> Q;void BFSTraverse(adjlist adjl) { //广度优先搜索edgenode *w;int i,j;printf("\n\t\t广度优先搜索:");for( i=0;i<maxlen;i++)visit[i]=0;for(i=0;i<=adjl.vexnum;i++){if(!visit[i]){visit[i]=1;printf("%c ",adjl.adjs[i].data);Q.push(i);while(!Q.empty()){j=Q.front();Q.pop();for( w=adjl.adjs[i].link;w;w=w->next)if(!visit[w->adjvex]){visit[w->adjvex]=1;printf("%c ",adjl.adjs[w->adjvex-1].data);Q.push(w->adjvex);}}}}}status initstack(stackstru *s){ //构造空栈s->top=0;return ok;}status push(stackstru *s,int x) { //进栈if (s->top==maxlen)printf("the stack is overflow!\n");else{s->top=s->top+1;s->stack[s->top]=x;}return 1;}status pop(stackstru *s) //出栈{int y;if(s->top==0)printf("the stack is empty!\n");else{y=s->stack[s->top];s->top=s->top-1;}return y;}status stackempty(stackstru *s) //判断栈是否为空{ if (s->top==maxlen) return (true);else return (false);}int TopologicalSort(adjlist adjl) //拓扑排序{stack <int> S;edgenode *p;int i,j,count=0;printf("\n拓扑排序:");for(i=0;i<=adjl.vexnum;i++)if(adjl.adjs[i].id==0)S.push(i);count=0;while(!S.empty()){j=S.top(); S.pop();count++;printf("(%d %c) ",j,adjl.adjs[j].data);for(p=adjl.adjs[i].link;p;p=p->next){int k=p->adjvex;int d=--(adjl.adjs[k].id);if(!d)S.push(k);}}if(count<adjl.vexnum){ printf("\n网中有环!\n");return error;}else return ok;}void prim(graph g){int i,j,k,min;int lowcost[maxlen];int closet[maxlen];printf("最小生成树的边为:\n");for(i=1;i<g.vexnum;i++){lowcost[i]=g.arcs[0][i];closet[i]=1;}closet[1]=0;j=1;for(i=1;i<g.vexnum;i++){min=lowcost[j];k=i;for(j=1;j<g.vexnum;j++)if(lowcost[j]<min&&closet[j]!=0){min=lowcost[j];k=j;}printf("(%c,%c),",g.vexs[k-1],g.vexs[closet[k-1]]);closet[k]=0;for(j=1;j<g.vexnum;j++)if(g.arcs[k][j]<lowcost[j]&&closet[j]!=0){lowcost[j]=g.arcs[k][j];closet[j]=k;}}}int ve[maxlen];int vl[maxlen];status toporder(adjlist adjl,stackstru *t){ //关键路径int i,j,count,k;edgenode *p;initstack(s);initstack(t);for(i=0;i<adjl.vexnum;i++)if(adjl.adjs[i].id==0) push(s,i);count=0;for(i=0;i<adjl.vexnum;i++) ve[i]=0;while(!stackempty(s)){j=pop(s);push(t,j);++count;for(p=adjl.adjs[j].link;p;p=p->next){k=p->adjvex;if(--adjl.adjs[k-1].id==0) push(s,k-1);if(ve[j]+(p->info)>ve[k-1]) ve[k-1]=ve[j]+(p->info);}}if(count<adjl.vexnum) return error;else return ok;}int criticalpath(adjlist adjl){int i,j,k,dut,ee,el;edgenode *p;if(!toporder(adjl,t)) return error;for(i=0;i<adjl.vexnum;i++) vl[i]=ve[i-1];printf("关键路径为:\n");while(!stackempty(t))for(j=pop(t), p=adjl.adjs[j].link;p;p=p->next){k=p->adjvex; dut=(p->info);if(vl[k]-dut<vl[j]) vl[j]=vl[k]-dut;}for(j=0;j<adjl.vexnum;++j)for(p=adjl.adjs[j].link;p;p=p->next){k=p->adjvex;dut=p->info;ee=ve[j];el=vl[k-1]-dut;if(ee==el) printf("(%c,%c)->",adjl.adjs[j].data,adjl.adjs[k-1].data);}return ok;}void shortpath_dijkstra(graph g) //有向网的最短路径{int cost[maxlen][maxlen];int dist[maxlen];int path[maxlen];int s[maxlen];int i,j,v0,min,u;printf("\n请输入起点的编号:");scanf("%d",&v0);v0--;for(i=0;i<g.vexnum;i++){for(j=0;j<g.vexnum;j++)cost[i][j]=g.arcs[i][j];}for(i=0;i<g.vexnum;i++){dist[i]=cost[v0][i];if(dist[i]<large&&dist[i]>0) path[i]=v0;s[i]=0;}s[v0]=1;for(i=0;i<g.vexnum;i++){min=large;u=v0;for(j=0;j<g.vexnum;j++)if(s[j]==0&&dist[j]<min){min=dist[j];u=j;}s[u]=1;for(j=0;j<g.vexnum;j++)if(s[j]==0&&dist[u]+cost[u][j]<dist[j]){dist[j]=dist[u]+cost[u][j];path[j]=u;}}printf("\n顶点%d到各顶点的最短路径长度为:\n",v0);for(i=0;i<g.vexnum;i++)if(s[i]==1){u=i;while(u!=v0){ printf("%4c<-",g.vexs[u]);u=path[u];}printf("%4c",g.vexs[u]);printf(":%d\n",path[i]);}else printf("%4c<-%4c:无路径\n",g.vexs[i],g.vexs[v0]);}void ShowMainMenu(){printf("\n");printf("**************图的基本操作及应用***************\n");printf("* 1 无向图的基本操作及应用*\n");printf("* 2 有向图的基本操作及应用*\n");printf("* 3 无向网的基本操作及应用*\n");printf("* 4 有向网的基本操作及应用*\n");printf("* 5 退出\n");printf("***********************************************\n");}void UDG(){int n;do{printf("\n");printf("**************无向图的基本操作及应用***************\n");printf("* 1 创建无向图的邻接矩阵*\n");printf("* 2 创建无向图的邻接表*\n");printf("* 3 无向图的深度优先遍历*\n");printf("* 4 无向图的广度优先遍历*\n");printf("* 5 退出\n");printf("***************************************************\n");printf("请选择:");scanf("%d",&n);switch(n){case 1:printf("----------wait-------");creategraph(g);break; //邻接矩阵case 2:printf("----------wait-------");createlist (g,adjl);break; //邻接表case 3:printf("----------wait-------");DFSTraverse(adjl);break; //深度优先搜索case 4:printf("----------wait-------");BFSTraverse(adjl);break; //广度优先搜索case 5:break;default:printf("ERROR!");}}while(n!=5);}void DG(){int n;do{printf("\n");printf("**************有向图的基本操作及应用***************\n");printf("* 1 创建有向图的邻接矩阵*\n");printf("* 2 创建有向图的邻接表*\n");printf("* 3 拓扑排序*\n");printf("* 4 退出*\n");printf("***************************************************\n");printf("请选择:");scanf("%d",&n);switch(n){case 1:printf("--------wait-------");creategraph(g);break; //邻接矩阵case 2:printf("--------wait-------");createlist (g,adjl);break; //邻接表case 3:printf("--------wait-------");createlist(g,adjl);TopologicalSort(adjl);break; //拓扑排序case 4:break; //退出default:printf("ERROR!");}}while(n!=4);}void UDN(){int n;do{printf("\n");printf("**************无向网的基本操作及应用***************\n");printf("* 1 创建无向网的邻接矩阵*\n");printf("* 2 创建无向网的邻接表*\n");printf("* 3 Prim算法求最小生成树*\n");printf("* 4 kraskal算法求最小生成树*\n");printf("* 5 退出\n");printf("***************************************************\n");printf("请选择:");scanf("%d",&n);switch(n){case 1:printf("---------wait-------");creategraph(g);break; // 创建无向网的邻接矩阵case 2:printf("--- ----wait-------");createlist (g,adjl);break; // 创建无向网的邻接表case 3:printf("---------wait-------");prim(g);break; //Prim算法求最小生成树case 4:printf("---------wait-------");break;case 5:break;default:printf("ERROR!");}}while(n!=5);}void DN(){int n;do{printf("\n");printf("**************有向网的基本操作及应用***************\n");printf("* 1 创建有向网的邻接矩阵*\n");printf("* 2 创建有向网的邻接表*\n");printf("* 3 关键路径*\n");printf("* 4 单源顶点最短路径问题*\n");printf("* 5 退出\n");printf("***************************************************\n");printf("请选择:");scanf("%d",&n);switch(n){case 1:printf("---------wait-------");creategraph(g);break; //创建有向网的邻接矩阵case 2:printf("---------wait-------");createlist (g,adjl);break; //创建有向网的邻接表case 3:printf("---------wait-------");criticalpath(adjl);break; //关键路径case 4:printf("---------wait-------");criticalpath(adjl);break; //单源顶点最短路径问题case 5:break; //退出default:printf("ERROR!");}while(n!=5);}void main(){int i,j,k,h,n;do{ShowMainMenu();printf("请选择:");scanf("%d",&n);if(n>5) error;else{g.kind=n;h=n;printf("请输入顶点数,边数:");scanf("%d,%d",&i,&j);g.vexnum=i;adjl.vexnum=i;g.arcnum=j;adjl.arcnum=j;for (i=0;i<g.vexnum;i++){printf("第%d个顶点的信息:",i+1);scanf("%s",&g.vexs[i]);adjl.adjs[i].data=g.vexs[i];adjl.adjs[i].link=null;adjl.adjs[i].id=0;}for (k=1;k<=g.arcnum;k++){//label:if (g.kind==2||g.kind==4)printf("第%d条边的起点编号,终点编号:",k);else printf("第%d条边的两个顶点的编号:",k);scanf("%d,%d",&i,&j);g.a[k-1]=i;g.b[k-1]=j;while (i<1||i>g.vexnum||j<1||j>g.vexnum){printf(" 编号超出范围,重新输入");//goto label;}if (g.kind==3||g.kind==4){printf("\t该边的权值:");scanf("%d",&h);g.h[k-1]=h;}else g.h[k-1]=null;adjl.adjs[i].id++;}switch(n){case 1:UDG();break;case 2:DG();break;case 3:UDN();break;case 4:DN();break;case 5:break;default:printf("ERROR!");break;}}while(n!=5);}三、测试a)程序开始运行,进入选择界面b)选择无向图,并创建无向图C)基于已创建的的无向图选择各项具体的操作四、难点与收获这次的实习报告相对我而言算是比较难的,因为在学这门课程的时候就没怎么专心听讲,所以在拿到计划书的时候,对很多地方感觉很陌生,甚至有一种没办法动手的感觉,加之开始学JAVA以后就很少用C语言编写程序,导致对很多很简单的东西都很陌生,所以熟悉整个C语言的编程环境都花了一段时间。
离散数学图的邻接矩阵的教学设计
离散 数 学是 信 息学 科 尤 其 是 计 算机 学 科 的一 门重 要
本文主要论述教给学生利用邻接矩阵的方法解决一
些 图论 问题 ,并对 一些方 法进 行设 计 。
的专业基础课程 ,而图论是建立和处理离散数学模 型的
一
个 重 要 工 具 ,是 一 门实用 性 很 强 的 学 科 。 它在 诸 如 社
好 的基 础 。
2 )判 断 图 的两个 顶 点是 否连 接 ,并且 计算 其 距离 。 在 只有 n 个顶 点 的 图G 中,如 果 点v与v之 间存 在路 的话 , 那 么必 然 存在 一 条 长度 小 于n 的真 路 。根据 上 面 介绍 的 定 理 ,在A, . A- — 个 矩 阵 中 ,至少 有 一个 A, A… , n这n 1 I
3 4
张 华离 数 图邻 矩 的 学计 爱 : 散 学 的 接 阵 教 设
教学 园地
1.9 9 j is. 6 149 .0 13 .3 0 3 6 / . s n 1 7 — 8 X 2 1. 0 0 4
离散数学 图的邻接矩 阵 的教 学设计
张爱华 华 中科技大学计算机科 学与技术学 院 武汉 4 0 7 304
的表现成功的机会 。小组讨论成员之 间的这种合作的能 ‘用 ,并 可 以推 而广 之 。 参考文献 [] 1 曾琦. 合作学习的基本要素 [] 学科教育,0 06 :- 2 J. 20 () 7 1. [] 2 严云芬. 建构主义学习理论综述 [] 当代教育论坛,0 5 1S :5 3. J. 20 (5 )3— 6
[] 3 明丽 娟. 小组 讨论 式教 学法 在英 语 教学 中 的运 用 [] 宁教 育行政 学 院学报 ,0 62 (0 :0 J辽 2 0 ,3 1)8 .
邻接矩阵的课程设计
邻接矩阵的课程设计一、教学目标本节课的教学目标是让学生掌握邻接矩阵的概念、性质及其在图的表示中的应用。
具体来说,知识目标包括:1.理解邻接矩阵的定义和性质。
2.掌握邻接矩阵在图的表示中的应用。
技能目标包括:1.能够熟练地运用邻接矩阵表示图。
2.能够运用邻接矩阵解决图的一些基本问题。
情感态度价值观目标包括:1.培养学生对图论的兴趣,使其能够主动学习图论的相关知识。
2.培养学生团队合作的精神,使其在解决问题时能够与他人共同探讨。
二、教学内容本节课的教学内容主要包括邻接矩阵的定义、性质及其在图的表示中的应用。
具体安排如下:1.引入邻接矩阵的概念,解释其定义和性质。
2.讲解邻接矩阵在图的表示中的应用,例如判断两顶点是否相邻、查找顶点的度等。
3.通过例题和练习题,让学生巩固邻接矩阵的概念和应用。
三、教学方法为了激发学生的学习兴趣和主动性,本节课将采用多种教学方法,如讲授法、讨论法、案例分析法等。
具体安排如下:1.通过讲授法,讲解邻接矩阵的定义、性质和应用。
2.采用讨论法,让学生分组讨论邻接矩阵在图的表示中的应用,促进学生之间的交流。
3.通过案例分析法,分析实际问题,让学生学会将邻接矩阵应用于解决实际问题。
四、教学资源为了支持教学内容和教学方法的实施,丰富学生的学习体验,我们将准备以下教学资源:1.教材:邻接矩阵的相关内容。
2.参考书:图论、线性代数等相关书籍。
3.多媒体资料:PPT、动画等辅助教学材料。
4.实验设备:计算机、投影仪等。
通过以上教学资源,我们将帮助学生更好地理解和掌握邻接矩阵的知识,提高他们解决实际问题的能力。
五、教学评估为了全面、客观地评估学生的学习成果,我们将采用多种评估方式,包括平时表现、作业和考试等。
具体安排如下:1.平时表现:通过观察学生在课堂上的参与程度、提问回答等情况,评估他们的学习态度和理解程度。
2.作业:布置与邻接矩阵相关的练习题,评估学生对知识的掌握程度。
3.考试:设计涵盖邻接矩阵概念、性质和应用的试题,评估学生的综合运用能力。
以邻接矩阵方式确定有向网课程设计报告
以邻接矩阵方式确定有向网课程设计报告以邻接矩阵方式确定有向网课程设计报告《数据结构》课程设计报告设计题目:以邻接矩阵方式确定有向网班级:姓名:学号:完成日期:一、需求分析1、运行环境(软、硬件环境):处理器:英特尔酷睿(Core) i5-2410M CPU 2.30GHz物理内存:2G操作系统:Microsoft Windowns 7开发环境:Microsoft Visual Studio 20082、程序所实现的功能:(1)建立并显示出它的邻接链表;(2)以非递归的方式进行深度优先遍历,显示遍历的结果,(并随时显示栈的入、出情况);(3)对改图进行拓扑排序,显示拓扑排序的结果,并随时显示入度域的变化情况;(4)给出某一确定顶点到所有其他顶点的最短路径;3、程序的输入,包含输入的数据格式和说明:(1)输入节点数个数(2)输入顶点信息(空格隔开)(3)输入权值信息(以弧尾值弧头值权值信息,空格隔开0 0 0结束;)文档由风行播放器/doc/2113242896.html,/暴风影音 2014:/doc/2113242896.html,/整理4、程序的输出,程序输出的形式:(1)邻接链表输出(2)深度优先遍历输出(3)拓扑排序输出(4)最短路径输出5、测试数据:(1)节点个数:5个(2)顶点信息:a b c d e(3)权值信息:a b 1 b c 2 c d 3 d e 4 a d 5 d c 6 0 0 0二、设计说明1、算法设计的思想:建程序主要是通过建立一个图的模板类来调用相应的构造函数以及相应的成员函数来实现其功能,首先用结构体来存储边节点和顶点节点,用邻接矩阵来存储此有向图,遍历的过程采用双从循环来使得遍历达到最底端,最短路径采用了递归的思想循环调用最短路径函数来完成最短路径的查找,拓扑排序中首先优先输出入度为零的节点,然后通过删除该节点继续此过程进行排序。
2、主要的数据结构设计说明:图的邻接矩阵结构设计:顶点数、弧数、矩阵数组、和点数组栈结构:包括栈顶和栈底点结构:包括顶点和弧相关的指针信息。
“邻接矩阵表示的带权有向图(网)”演示程序
班级:信息1102 姓名:贾孟涛========实习报告十四“邻接矩阵表示的带权有向图(网)”演示程序==========(一)、程序的功能和特点该程序可以建立有向图的带权邻接矩阵,能够对建立的邻接矩阵进行添加顶点,添加边和删除顶点,删除边的操作,并能显示输出邻接矩阵。
该程序的特点是采用java面向对象语言,对边,顶点和邻接矩阵用类进行封装。
采用链式存储结构。
(二)、程序的算法设计算法一:“插入一个顶点”算法:1.【逻辑结构与存储结构设计】逻辑结构:线性结构。
存储结构:顺序存储与链式存储结合。
2.【基本操作设计】文字说明:创建新结点,找到结点L位置,在 L后插入新结点。
3.【算法设计】文字说明:(1).首先判断顶点表是否满。
(2).若满则插入失败,放回false。
(3).顶点表若不满,创建新顶点,将新顶点加入顶点表。
(4).插入顶点成功,返回true。
4.【高级语言代码】//插入一个顶点public int InsertVertex ( char vertex ){if(IsGraphFull()) return -1; //插入失败//顶点表增加一个元素VerticesList[CurrentVertices]=vertex;//邻接矩阵增加一行一列for ( int j = 0;j <=CurrentVertices;j++ ) {Edge[CurrentEdges][j]=MaxValue;Edge[j][CurrentEdges]=MaxValue;}Edge[CurrentEdges][CurrentEdges]=0;CurrentVertices++;return CurrentVertices; //插入位置}算法二:“插入一条边”算法:1.【逻辑结构与存储结构设计】逻辑结构:线性结构。
存储结构:链式存储结构。
3.【基本操作设计】文字说明:创建新边结点,再将新创建的边结点插入图中。
课程设计四
图的应用一、邻接表和邻接矩阵储存1.需求分析对于下图所示的有向图G,编写一个程序完成如下功能:1).建立G的邻接矩阵并输出之2).由G的邻接矩阵产生邻接表并输出之3).再由2的邻接表产生对应的邻接矩阵并输出之2.系统设计1).图的抽象数据类型定义:ADT Graph{数据对象V:V是具有相同特性的数据元素的集合,称为顶点集数据关系R:R={VR}VR={<v,w>|v,w∈V且P(v,w),<v,w>表示从v到w的弧,谓词P(v,w)定义了弧<v,w>的意义或信息}基本操作P: CreatGraph(&G,V,VR)初始条件:V是图的顶点集,VR是图中弧的集合操作结果:按V和VR的定义构造图G DestroyGraph(&G)初始条件:图G存在操作结果:销毁图G InsertVex(&G,v)初始条件:图G存在,v和图中顶点有相同特征操作结果:在图G中增添新顶点v……InsertArc(&G,v,w)初始条件:图G存在,v和w是G中两个顶点操作结果:在G中增添弧<v,w>,若G是无向的则还增添对称弧<w,v>……DFSTraverse(G,Visit())初始条件:图G存在,Visit是顶点的应用函数操作结果:对图进行深度优先遍历,在遍历过程中对每个顶点调用函数Visit一次且仅一次。
一旦Visit()失败,则操作失败 BFSTraverse(G,Visit())初始条件:图G存在,Visit是顶点的应用函数操作结果:对图进行广度优先遍历,在遍历过程中对每个顶点调用函数Visit一次且仅一次。
一旦Visit()失败,则操作失败 }ADT Graph2).主程序的流程:调用CreateMG函数创建邻接矩阵M;调用PrintMatrix函数输出邻接矩阵M调用CreateMGtoDN函数,由邻接矩阵M创建邻接表G调用PrintDN函数输出邻接表G调用CreateDNtoMG函数,由邻接表M创建邻接矩阵N调用PrintMatrix函数输出邻接矩阵N 3.函数关系调用图:3.调试分析(1)在MGraph的定义中有枚举类型 typedefenum{DG,DN,UDG,UDN}GraphKind;//{有向图,有向网,无向图,无向网}赋值语句G.kind(int)=M.kind(GraphKind);是正确的,而反过来M.kind=G.kind则是错误的,要加上那个强制转换M.kind=GraphKind(G.kind);枚举类型enum{DG,DN,UDG,UDN} 会自动赋值DG=0;DN=1,UDG=2,UDN=3;可以自动从GraphKind类型转换到int型,但不会自动从int型转换到GraphKind类型(2)算法的时间复杂度分析: CreateMG、CreateMGtoDN、CreateDNtoMG、PrintMatrix、PrintDN的时间复杂度均为O(n2 ) n为图的顶点数,所以main:T(n)= O(n2)4.测试结果用需求分析中的测试数据输入:输出:5、用户手册(1)输入顶点数和弧数;(2)输入顶点内容;(3)按行序输入邻接矩阵,输入各弧相应权值(4)回车输出邻接矩阵M、邻接表G和邻接矩阵N 6、附录源程序:#include <stdio.h>#include <stdlib.h>#define MAX_VERTEX_NUM 20typedef int VRType;typedef int InfoType;typedef int VertexType;typedef enum{DG,DN,UDG,UDN}GraphKind;//{有向图,有向网,无向图,无向网}typedef struct ArcCell{VRType adj;//VRType是顶点关系类型,对无权图用1或0表示是否相邻;//对带权图则为权值类型InfoType *info;//该弧相关信息的指针}ArcCell,AdjMatrix[MAX_VERTEX_NUM][MAX_VERTEX_NU M];typedef struct{VertexType vexs[MAX_VERTEX_NUM];//顶点向量AdjMatrix arcs;//邻接矩阵int vexnum,arcnum;//图的当前顶点数和弧数GraphKind kind;//图的种类标志}MGraph;void CreateMG(MGraph &M){ int i,j;M.kind=DN;printf("输入顶点数:");scanf("%d",&M.vexnum);printf("输入弧数:");scanf("%d",&M.arcnum);printf("输入顶点:\n");for(i=0;i<M.vexnum;i++) scanf("%d",&M.vexs[i]); printf("建立邻接矩阵:\n");for(i=0;i<M.vexnum;i++)for(j=0;j<M.vexnum;j++)scanf("%d",&M.arcs[i][j].adj);printf("输入相应权值:\n");for(i=0;i<M.vexnum;i++)for(j=0;j<M.vexnum;j++)if(M.arcs[i][j].adj){scanf("%d",&M.arcs[i][j].info);}}typedef struct ArcNode{int adjvex;//该弧所指向的顶点在数组中的下标struct ArcNode *nextarc;InfoType *info;//该弧相关信息的指针}ArcNode;typedef struct VNode{VertexType data;//顶点信息ArcNode *firstarc;//指向第一条依附该顶点的弧的指针}VNode,AdjList[MAX_VERTEX_NUM];typedef struct{AdjList vertices;int vexnum,arcnum;//图的当前顶点数和弧数int kind;//图的种类标志}ALGraph;void PrintDN(ALGraph G){int i;ArcNode *p;printf("顶点:\n");for(i=0;i<G.vexnum;++i)printf("%2d",G.vertices[i].data);printf("\n弧:\n"); for(i=0;i<G.vexnum;++i){p=G.vertices[i].firstarc;while(p){printf("%d→%d(%d)\t",i,p->adjvex,p->info);p=p->nextarc;} printf("\n");}//for }void CreateMGtoDN(ALGraph &G,MGraph M){ //采用邻接表存储表示,构造有向图G(G.kind=DN)int i,j;ArcNode *p;G.kind=M.kind;G.vexnum=M.vexnum;G.arcnum=M.arcnum;for(i=0;i<G.vexnum;++i){//构造表头向量G.vertices[i].data=M.vexs[i];G.vertices[i].firstarc=NULL;//初始化指针 }for(i=0;i<G.vexnum;++i)for(j=0;j<G.vexnum;++j)if(M.arcs[i][j].adj==1){p=(ArcNode*)malloc(sizeof(ArcNode));p->adjvex=j;p->nextarc=G.vertices[i].firstarc;p->info=M.arcs[i][j].info;G.vertices[i].firstarc=p;}}void CreateDNtoMG(MGraph &M,ALGraph G){int i,j;ArcNode *p;M.kind=GraphKind(G.kind);M.vexnum=G.vexnum;M.arcnum=G.arcnum;for(i=0;i<M.vexnum;++i) M.vexs[i]=G.vertices[i].data; for(i=0;i<M.vexnum;++i){p=G.vertices[i].firstarc;while(p){M.arcs[i][p->adjvex].adj=1;p=p->nextarc;}//whilefor(j=0;j<M.vexnum;++j)if(M.arcs[i][j].adj!=1)M.arcs[i][j].adj=0; }//for }void PrintMatrix(MGraph M){int i,j;for(i=0;i<M.vexnum;++i){for(j=0;j<M.vexnum;++j)printf("%2d",M.arcs[i][j].adj);printf("\n");}}void main(){MGraph M,N;ALGraph G;CreateMG(M);PrintMatrix(M);CreateMGtoDN(G,M);PrintDN(G);CreateDNtoMG(N,G);PrintMatrix(N);}二、邻接矩阵与邻接表的转换图的邻接矩阵存储方法具有如下几个特征:1)无向图的邻接矩阵一定是一个对称矩阵。
数据结构有向网络实验报告
2,数据输入
从键盘输入n个整型数据,来表示图的顶点,再从键盘输入e组有序数对来表示图的e条边,与此同时,输入相应边的权值,权值定义为浮点型,数据间都以逗号间隔,以回车作为结束符。本程序中定义图的顶点数为7,边数为10。
3,数据输出
从键盘输入数据后,由BFSL函数对图进行广度优先搜索遍历,再由preorder函数输出生成树的边集,输出结果都是整型数据。
s=T[i]->headptr->next;
T[i]->headptr->next=sp;
sp->next=s;
visited[p->adjvex-1]=1;
ENQUEUE(Q,p->adjvex-1);//访问过的顶点入队
}p=p->next;找vi+1的下一个邻接点
(2)函数声明:void preorder(ctree *T)
}
p=ga[i].link;//取vi+1的边表头指针
while(p!=NULL)//依次搜索v(i+1)的邻接点
{
if (! visited[p->adjvex-1])//访问v(i+1)未曾访问的邻接点
{
sp=(link*)malloc(sizeof(link));
sp->child=p->adjvex;
s->adjvex=j; //邻接点序号为j
s->next=ga[i].link;
s->weight=w;
ga[i].link=s; //将新结点*s插入顶点vi的边表头部
}
}
void BFSL(int k)//从v(k+1)出发广度优先搜索图ga
图及其应用实验报告
一、实验目的、意义(1)熟悉图的邻接矩阵的表示方法;(2)掌握建立图的邻接矩阵算法;(3)加深对图的理解,逐步培养解决实际问题的编程能力二、实验内容及要求求有向网络中单源点到其它各个顶点v的最短路径。
具体要求:(1)建立图的邻接矩阵;(2)求有向网中单源点到其它各个顶点v的最短路径P[v]及带权长度D[v]。
三、实验所涉及的知识点1.图的邻接矩阵的表示方法;2.建立图的邻接矩阵算法;3.有向网中求最短路径算法和带权长度。
四、实验记录(调试过程及调试中遇到的问题及解决办法,其他算法的存在与实践等。
) 实验中对最短路径和求带权长度的算法不是很理解,这部分程序的编写对我来说难度也比较大。
通过上网查找资料,把程序调了出来。
五、实验结果及分析(所输入的数据及相应的运行结果,运行结果要有提示信息,运行结果采用截图方式给出。
)六、总结与体会(调试程序的心得与体会,若实验课上未完成调试,要认真找出错误并分析原因等。
)七、程序清单(包含注释)#include<string.h>#include<ctype.h>#include<malloc.h>#include<limits.h>#include<stdio.h>#include<stdlib.h>#include<math.h>#define TRUE 1#define FALSE 0#define OK 1#define MAX_NAME 5 //顶点字符串的最大长度+1#define MAX_INFO 20 //相关信息字符串的最大长度+1#define MAX_VERTEX_NUM 20//最大顶点数#define INFINITY INT_MAX //用整形最大值代替无穷typedef int VRType;typedef char InfoType;typedef char VertexType[MAX_NAME];typedef char InfoType;typedef int Status;typedef int Boolean;typedef int PathMatrix[MAX_VERTEX_NUM][MAX_VERTEX_NUM];typedef int ShortPathTable[MAX_VERTEX_NUM];typedef enum{DG,DN,AG,AN}GraphKind;typedef struct{VRType adj; //顶点关系类型,无权图,用1/0表示相邻否,对于带权图,则为权值类型。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
以邻接矩阵方式确定有向网课程设计报告《数据结构》课程设计报告设计题目:以邻接矩阵方式确定有向网班级:姓名:学号:完成日期:一、需求分析1、运行环境(软、硬件环境):处理器:英特尔酷睿(Core) i5-2410M CPU 2.30GHz物理内存:2G操作系统:Microsoft Windowns 7开发环境:Microsoft Visual Studio 20082、程序所实现的功能:(1)建立并显示出它的邻接链表;(2)以非递归的方式进行深度优先遍历,显示遍历的结果,(并随时显示栈的入、出情况);(3)对改图进行拓扑排序,显示拓扑排序的结果,并随时显示入度域的变化情况;(4)给出某一确定顶点到所有其他顶点的最短路径;3、程序的输入,包含输入的数据格式和说明:(1)输入节点数个数(2)输入顶点信息(空格隔开)(3)输入权值信息(以弧尾值弧头值权值信息,空格隔开 0 0 0结束;)文档由风行播放器/暴风影音 2014:/整理4、程序的输出,程序输出的形式:(1)邻接链表输出(2)深度优先遍历输出(3)拓扑排序输出(4)最短路径输出5、测试数据:(1)节点个数:5个(2)顶点信息:a b c d e(3)权值信息:a b 1 b c 2 c d 3 d e 4 a d 5 d c 6 0 0 0二、设计说明1、算法设计的思想:建程序主要是通过建立一个图的模板类来调用相应的构造函数以及相应的成员函数来实现其功能,首先用结构体来存储边节点和顶点节点,用邻接矩阵来存储此有向图,遍历的过程采用双从循环来使得遍历达到最底端,最短路径采用了递归的思想循环调用最短路径函数来完成最短路径的查找,拓扑排序中首先优先输出入度为零的节点,然后通过删除该节点继续此过程进行排序。
2、主要的数据结构设计说明:图的邻接矩阵结构设计:顶点数、弧数、矩阵数组、和点数组栈结构:包括栈顶和栈底点结构:包括顶点和弧相关的指针信息。
3、程序的主要流程图:有向图输出邻接表深度优先遍拓扑排序入度域变化最短路径历4、主要模块和函数:1、邻接矩阵创建有向网void CreatGraph(MGraph *g) 伪码:依次存储节点数、顶点信息、权值2、打印有向网的邻接矩阵void PrintGraph(MGraph *g) 伪码:依次打印邻接矩阵3、打印有向网的邻接表void PrintList(MGraph *g)伪码:输出矩阵每行不为零值纵坐标对应的节点4、非递归深度优先遍历void DFSTraverse(MGraph *g)伪码:1.从右向左依次把邻接矩阵第一行非零值纵坐标对应的节点数入栈,并将最后入栈值出栈;2.再将最后入栈值定为横坐标,重复上述操作,直到空;3.出栈,重复第二步操作;4.重复第三部操作,直到栈空;5、获取每个节点的入度void FindInDegree()伪码:获取邻接矩阵每行非零值个数6、拓扑排序伪码:int TopologicalSort(MGraph *g)1.先将度为零节点入栈2.出栈,对i 号节点的每个邻接点入度减13.若入度减为0,则入栈4.重复2,3 步,直至栈空7、任意两点最短距离void ShortestPath_FLOYD(MGraph *g)伪码:先看两点之间有无直接路径,若有,则看有无通过中间点更短若无,则看有无中间点连通三、源程序代码:#include <iostream>#include<stdio.h>#include<stdlib.h>using namespace std;#define MAX_VERTEX_NUM 20 #define STACK_INIT_SIZE 100 #define STACKINCREMENT 10 #define OVERFLOW 0#define ERROR 0#define OK 1#define INFINITY 100//最大顶点个数//存储空间初始分配量//存储空间分配增量typedef struct ArcCell //图的邻接矩阵结构定义{char adj;int *info; }VertexNode; typedef struct { //顶点//弧相关信息指针VertexNode vexs[MAX_VERTEX_NUM];intarcs[MAX_VERTEX_NUM][MAX_VERTEX_NU M]; //顶点向量//邻接矩阵int vexnum,arcnum;}MGraph;typedef struct{//定点数和弧数int *base;int *top;int stacksize; }SqStack;/*函数名称:函数功能描述://栈底指针//栈顶指针//存储空间findnode返回结点在数组位置函数调用之前的预备条件:定义并赋值结点数组返回后的处理:返回值(如果有的话):函数的输入参数:intSqStack &S,结点字符a函*/int findnode(char a,MGraph *S){for(int i=1;i<(S->vexnum+1);i++){if (S->vexs[i].adj ==a)return i;}return -1;}/*函数名称:函数功能描述:InitStack构造一个空栈函数调用之前的预备条件:定义邻接矩阵结构体返回后的处理:返回值(如果有的话):函数的输入参数:OVERFLOW 或OK SqStack &S函数的输出参数:函数的抽象算法(伪码):存储分配*/int InitStack(SqStack &S) //构造一个空栈4if(!S.base) //存储分配失败return OVERFLOW;S.top=S.base;S.stacksize=STACK_INIT_SIZE;return OK;}/*函数名称:函数功能描述:StackEmpty判断栈是否为空栈函数调用之前的预备条件:已构造一个栈返回后的处理:返回值(如果有的话):函数的输入参数:OK 或ERROR SqStack &S函数的输出参数:函数的抽象算法(伪码):栈底与栈顶比较*/int StackEmpty(SqStack &S){if(S.top==S.base)return OK;elsereturn ERROR; }/*函数名称:函数功能描述://空栈Push插入新的栈顶元素函数调用之前的预备条件:已构造一个栈返回后的处理:返回值(如果有的话):函数的输入参数:OKSqStack &S,int e函数的输出参数:函数的抽象算法(伪码):指针移动*/int Push(SqStack &S,int e){if(S.top-S.base>=S.stacksize) //插入新的栈顶元素//栈满,追加存储空间{S.base=(int *)realloc(S.base,(S.stacksize+STACKINCREMENT) *sizeof(int));if(!S.base) //存储分配失败return(OVERFLOW);S.top=S.base+S.stacksize;S.stacksize+=STACKINCREMENT;}*S.top++=e;return OK; }/*函数名称:函数功能描述:GetTop获取的栈顶元素函数调用之前的预备条件:已构造一个栈返回后的处理:返回值(如果有的话):函数的输入参数:e 或ERROR SqStack &S,int e函数的输出参数:函数的抽象算法(伪码):指针移动*/int GetTop(SqStack &S,int &e){if(S.top==S.base)return ERROR;e=*(S.top-1);return e;}/*函数名称:函数功能描述:Pop删除栈顶元素函数调用之前的预备条件:已构造一个栈返回后的处理:返回值(如果有的话):函数的输入参数:函数的输出参数:eSqStack &S,int &e e函数的抽象算法(伪码):指针移动*/int Pop(SqStack &S,int &e){if(S.top==S.base)return ERROR;e=*--S.top;return e;}/*//删除栈顶元素函数名称:函数功能描述:CreatGraph邻接矩阵创建有向网函数调用之前的预备条件:定义邻接矩阵结构体返回后的处理:返回值(如果有的话):函数的输入参数:MGraph *g函数的输出参数:函数的抽象算法(伪码):依次存储节点数、顶点信息、权值*/void CreatGraph(MGraph *g)//邻接矩阵创建有向网{int i,j,m,o, p;char r1,r2;//m 权值cout<<"请输入节点数:\n";cin>>g->vexnum; //获取节点数cout<<"请输入有向网顶点信息(空格间开):\n";for(i=1;i<=g->vexnum;i++) {cin>>g->vexs[i].adj; }for(i=1;i<=g->vexnum;i++) //获取顶点信息//初始化邻接矩阵for(j=1;j<=g->vexnum;j++){g->arcs[i][j]=0;}cout<<"请输入权值信息(以弧尾值弧头值权值顺序,空格间开,0 0 0 结束):\n"; cin>>r1>>r2>>m; //权值信息} /* while(r1!='0'&&r2!='0'&&m!=0){o=findnode(r1,g);p=findnode(r2,g);g->arcs[o][p]=m;cin>>r1>>r2>>m;}//生成邻接矩阵转函数名称:函数功能描述:PrintList打印有向网的邻接表函数调用之前的预备条件:已创建有向网CreatGraph 返回后的处理:返回值(如果有的话):函数的输入参数:函数的输出参数:MGraph *g g->vexs[j].adj函数的抽象算法(伪码):输出矩阵每行不为零值纵坐标对应的节点*/void PrintList(MGraph *g)//打印有向网的邻接表{int i,j;for(i=1;i<=g->vexnum;i++){cout<<(g->vexs[i].adj);for(j=1;j<=g->vexnum;j++){if(g->arcs[i][j]!=0) //获取非零值{cout<<"-->"<<(g->vexs[j].adj);}}} /* }cout<<"-->NULL\n"; //一行结束,打印空函数名称:函数功能描述:DFSTraverse非递归深度优先遍历函数调用之前的预备条件:已创建有向网CreatGraph 返回后的处理:返回值(如果有的话):函数的输入参数:函数的输出参数:MGraph *g g->vexs[i].adj函数的抽象算法(伪码):1.从右向左依次把邻接矩阵第一行非零值纵坐标对应的节点数入栈,并将最后入栈值出栈;2.再将最后入栈值定为横坐标,重复上述操作,直到空;3.出栈,重复第二步操作;4.重复第三部操作,直到栈空;*/void DFSTraverse(MGraph *g){//非递归深度优先遍历int visited[MAX_VERTEX_NUM],i=1,j,e=1;SqStack s;InitStack(s);//visited[]标记向量,e 出栈值Push(s,i); //首节点入栈cout<<"插入栈顶元素:\n"<<i;cout<<"-->"<<g->vexs[i].adj<<endl;visited[i]=1; //有输出,即为1while(!StackEmpty(s)){i=e; //从e 行开始for(j=g->vexnum;j>=1;j--) //从右向左寻找{if(g->arcs[i][j]&&(visited[j]!=1)) //非零即入栈{Push(s,j);cout<<"插入栈顶元素:"<<j<<endl;}}Pop(s,e); //该行最左非零值入栈cout<<"删除栈顶元素:"<<e<<endl;if(visited[e]!=1) //未被标记{cout<<"-->"<< g->vexs[e].adj<<endl;visited[e]=1;}}}/*函数名称:函数功能描述:FindInDegree获取每个节点的入度,并存储在indegree 数组中函数调用之前的预备条件:已创建有向网CreatGraph 返回后的处理:返回值(如果有的话):函数的输入参数:函数的输出参数:MGraph *g indegree[]函数的抽象算法(伪码):获取邻接矩阵每行非零值个数*/void FindInDegree(MGraph *g,int indegree[MAX_VERTEX_NUM]) //获取每个节点的入度,并存储在indegree 数组中{int i,j,n; //n 入度for(i=1;i<=g->vexnum;i++){n=0;for(j=1;j<=g->vexnum;j++)} /* }if(g->arcs[j][i])n++;indegree[i]=n;//每行非零值个数//存储入度函数名称:函数功能描述:TopologicalSort 拓扑排序函数调用之前的预备条件:已创建有向网CreatGraph;获取每个节点的入度FindInDegree 返回后的处理:返回值(如果有的话):函数的输入参数:函数的输出参数:MGraph *g g->vexs[i].adj函数的抽象算法(伪码):1.先将度为零节点入栈2.出栈,对i 号节点的每个邻接点入度减13.若入度减为0,则入栈4.重复2,3 步,直至栈空*/int TopologicalSort(MGraph *g){// 拓扑排序int indegree[MAX_VERTEX_NUM],i,j,k,count;SqStack S;//count 输出顶点计数FindInDegree(g,indegree); InitStack(S);for(i=1;i<=g->vexnum;i++) //对各顶点求入度//建立零入度顶点栈if(!indegree[i]) //入度为零入栈Push(S,i);count=0;while(!StackEmpty(S)){Pop(S,i);cout<<"\n-->"<< g->vexs[i].adj;++count;for(j=1;j<=g->vexnum;j++){if(g->arcs[i][j]){k=j;if(!(--indegree[k]))Push(S,k);cout<<"\t 此时"<<g->vexs[k].adj<<"入度:"<<indegree[k];//若入度减为零,入栈}}}if (count<g->vexnum)return ERROR;elsereturn OK;}/*函数名称:函数功能描述://有回路ShortestPath_FLOYD 任意两点最短距离函数调用之前的预备条件:已创建有向网CreatGraph 返回后的处理:返回值(如果有的话):函数的输入参数:函数的输出参数:MGraph *g dist[i][j]函数的抽象算法(伪码):先看两点之间有无直接路径,若有,则看有无通过中间点更短若无,则看有无中间点连通*/void ShortestPath_FLOYD(MGraph *g)//任意两点最短距离{int dist[MAX_VERTEX_NUM][MAX_VERTEX_NUM];//dist[]两点间路径长度int i,j,k;for(i=1;i<=g->vexnum;i++) //初始化for(j=1;j<=g->vexnum;j++)dist[i][j]=g->arcs[i][j];for(i=1;i<=g->vexnum;i++){for(j=1;j<=g->vexnum;j++){cout<< g->vexs[i].adj<<"-->"<< g->vexs[j].adj<<":\t";for(k=1;k<=g->vexnum;k++)if(i!=j&&i!=k&&j!=k) //三点互不相同{if(dist[i][j]) //有直接路径{if(dist[i][k]&&dist[k][j])if(dist[i][j]>dist[i][k]+dist[k][j]) //有中间更短路径dist[i][j]=dist[i][k]+dist[k][j];}else{if(dist[i][k]&&dist[k][j])dist[i][j]=dist[i][k]+dist[k][j];//取中间路径}}cout<<dist[i][j]<<endl;}cout<<endl;}}void main()//主函数{MGraph *g=(MGraph *)malloc(sizeof(MGraph));CreatGraph(g);cout<<"***********************************************\n 邻接链表输出:\n";PrintList(g);cout<<"***********************************************\n 深度优先遍历:\n";DFSTraverse(g);cout<<"***********************************************\n 拓扑排序:";TopologicalSort(g);cout<<"\n***********************************************\n 最短路径:\n";ShortestPath_FLOYD(g);}四、输出结果:五:上机结果及体会1、实际完成情况说明:本次数据结构课程设计,在同学以及老师的帮助下,完成了实验题目所要 求的(1)建立并显示出它的邻接链表;(2)以非递归的方式进行深度优先遍历, 显示遍历的结果,(并随时显示栈的入、出情况)(3)对该图进行拓扑排序,显 示拓扑排序的结果,并随时 显示入度域的变化情况;(4)给出某一确定顶点到O(n+e)。