为了正常的体验网站,请在浏览器设置里面开启Javascript功能!

数据结构-求有向图的所有简单回路

2017-11-29 21页 doc 92KB 43阅读

用户头像

is_511210

暂无简介

举报
数据结构-求有向图的所有简单回路数据结构-求有向图的所有简单回路 课 程 设 计 报 告 课程设计名称:数据结构课程设计 课程设计题目:求有向图的所有简单回 路 院(系):计算机学院 专 业:计算机科学与技术(嵌入式方向) 班 级: 学 号: 姓 名: 指导教师: I 目 录 沈阳航空航天大学 .................................................................... 错误~未定义书签。 1 总体设计 ........................................
数据结构-求有向图的所有简单回路
数据结构-求有向图的所有简单回路 课 程 设 计 报 告 课程设计名称:数据结构课程设计 课程设计题目:求有向图的所有简单回 路 院(系):计算机学院 专 业:计算机科学与技术(嵌入式方向) 班 级: 学 号: 姓 名: 指导教师: I 目 录 沈阳航空航天大学 .................................................................... 错误~未定义书签。 1 总体设计 .................................................................................. 错误~未定义书签。 1.1 课设要求............................................................................. 错误~未定义书签。 1.2 设计原理............................................................................. 错误~未定义书签。 2 详细设计 .................................................................................. 错误~未定义书签。 2.1 算法与程序的设计与实现......................................... 错误~未定义书签。 2.1.1算法描述 ........................................................................ 错误~未定义书签。 2.1.2数据结构设计及用法说明 ........................................ 错误~未定义书签。 2.2 流程图的设计与实现..................................................... 错误~未定义书签。 3 核心数据结构函数的描述 .............................................. 错误~未定义书签。 3.1 建立邻接表的函数......................................................... 错误~未定义书签。 3.2 深度优先遍历函数......................................................... 错误~未定义书签。 4 程序测试及结果分析 .......................................................... 错误~未定义书签。 4.1 程序测试及结果............................................................. 错误~未定义书签。 参考文献 ........................................................................................ 错误~未定义书签。 附 录(关键部分程序清单) .............................................. 错误~未定义书签。 II 1 总体设计 1.1 课设要求 以合适方便的方式输入一个有向图,并在内部建立有向图的邻接表储存结构,有邻接表的形式储存有向图。然后根据有向图的储存结构,求出该有向图中所有的简单回路。输入有向图的方式简单方便,能形象方便的观察有向图的顶点名称,相关弧的关系。 要求如下: (1)熟悉图的邻接表储存结构及操作方式; (2)熟悉求简单回路的算法(利用深度优先遍历); (3)熟悉运用开发环境,基于VC++6.0的软件开发环境; (4)完成课程设计基本任务的设计及编码; (5)熟练掌握VC++6.0上的基本的调试方法。 1.2 设计原理 根据所学的知识,在利用邻接表时需要做三个工作:定义表结点类型;定义头结点类型;定义邻接表类型。再对储存的图进行深度优先遍历,并将遍历过的点进行标记,放入数组储存,当发现有被标记的点出现时则表示出现重复的顶点,为找到回路,打印出有向图的回路。 1 2 详细设计 2.1 算法与程序的设计与实现 在得到该课程设计任务书时,在对求有向图的所有简单回路的算法知识做了简单的回顾与学习。首先是邻接表储存有向图,由于有向边没有权值,所有在建立有向图的邻接表的时候去除了有关弧的信息。其次才用深度优先遍历的算法遍历有向图中所有的顶点,在遍历有向图时,对图中每个顶点至多调用一次DFS函数,因为一旦某个顶点被标记成为已被访问,就不再从它出发进行搜索了。因此,遍历有向图的过程实质上是对每个顶点查找其邻接点的过程。 2.1.1算法描述 (1)邻接表:邻接表是图的一种链式存储结构。在邻接表中,对图中每个顶点建立一个单链表,第i个单链表中的接点表示依附于顶点Vi的边(对有向图是以顶点Vi为尾的弧)。每个结点由3个域组成,其中邻接点域(adjvex)指示与顶点Vi邻接的点在图中的位置,链域(nextare)指示下一条边或弧的结点;数据域(info)储存和边或弧相关的信息,如权值等。每个链表上附设一个表头结点。在表头结点中,除了设有链域(firstarc)指向链表中第一个结点之外,还设有储存顶点Vi的名或其它有关信息的数据域(data)。如下图所示: adjvex nextarc info 图2.1.1 表结点 data firstarc 图2.1.2 头结点 (2)深度优先遍历:设x是当前被访问顶点,在对x做过访问标记后,选择一条从x出发的未检测过的边(x,y)。若发现顶点y已访问过,则重新 2 选择另一条从x出发的未检测过的边,否则沿边(x,y)到达未曾访问过的y,对y访问并将其标记为已访问过;然后从y开始搜索,直到搜索完从y出发的所有路径,即访问完所有从y出发可达的顶点之后,才回溯到顶点x,并且再选择一条从x出发的未检测过的边。上述过程直至从x出发的所有边都已检测过为止。此时,若x不是源点,则回溯到在x之前被访问过的顶点;否则图中所有和源点有路径相通的顶点(即从源点可达的所有顶点)都已被访问过,若图G是连通图,则遍历过程结束,否则继续选择一个尚未被访问的顶点作为新源点,进行新的搜索过程。 在本次课程设计中还需要对深度优先遍历进行递归,关于深度优先遍历的递归,首先访问出发点v,并将其标记为已访问过;然后依次从v出发搜索v的每个邻接点w。若w未曾访问过,则以w为新的出发点继续进行深度优先遍历,直至图中所有和源点v有路径相通的顶点(称为从源点可达的顶点)均已被访问为止。 2.1.2数据结构设计及用法说明 (1)邻接表的形式说明及其建表算法: 通过表头结点(可以链相接)通常以顺序结构的形式储存,以便随机访问任一顶点的链表。一个邻接表储存结构可以定于如下: //边表结点 Typedef struct ArcNode{ int adjvex;//邻接点域 struct node *nextarc; //链域 InfoType *info//若要表示边上的权,则应增加一个数据域 } ArcNode; //顶点表结点 typedef struct vnode{ VertexType data;//顶点域 EdgeNode *firstarc;//指向第一条依附该顶点的弧的指针 }VertexNode; //AdjList是邻接表类型 3 typedef VertexNode AdjList[MaxVertexNum]; typedef struct{ AdjList adjlist;//邻接表 int n,e;//图中当前顶点数和边数 }ALGraph; (2)深度优先遍历的算法说明: 在遍历图时,对图中每个顶点至多调用一次DFS函数,因为一旦某个顶点被标记成为已被访问,就不再从它出发进行搜索了。因此,遍历图的过程实质上是对每个顶点查找其邻接点的过程。 Boolean visited[MAX];//访问标志数组 Status(* VisitFunc)(int v);//函数变量 void DFS(Graph G,int v), //从第v个顶点出发递归地深度优先遍历图G visited[v] = TURE; VisitFunc(v);//访问第v个顶点 for(w=FirstAdjVex(G,v);w>=0;w =NextAdjVex(G,v,w)) if(~visited[w])DFS(G,w) , 4 2.2 流程图的设计与实现 (1)建立邻接表流程图如下: 开始 输入顶点个数和弧的条 数 输入顶点名称 Y 是否重复 N 输入弧的信息,弧的起点与 终点 Y 是否重复 N 根据顶点信息,将弧赋予当 前指针和指向下一弧的 指针 建立结点和顶点链表 N 是否弧已全部进行操 作 Y 5 结束 图2.2.1 建立邻接表流程图 (2)深度优先遍历的流程图如下: 开始 将顶点全部初始化为未遍 历 将当前顶点指针指向根顶 点 对当前顶点进行 操作并标记为遍 历 获取当前顶点的 将当前指针指向该顶下一个子顶点 点 N 对当前顶点进行操是否获得 作 Y 从顶点数记录中减 将当前顶点放入一回到上一顶点 数组保存,然后 将当前指针指向 获得的顶点 N N 是否该顶点周围 的子顶点都已遍 历 该顶点是否与 第一个顶点相 Y 同 Y 输出保存有顶点 信息的数组 6 结束 图2.2.2 深度遍历流程图 7 3 核心数据结构函数的描述 3.1 建立邻接表的函数 函数名称:int CreateADG(ALGraph &g) 函数功能:实现在键盘上输入有向图顶点数、顶点名称(用整数表示,如 1就表示顶点1)、弧数以及弧的顶点与起点,并用邻接表储存图。 函数具体代码如下: int CreateADG(ALGraph &g){ int i,j,k,l; ArcNode *p; int v1,v2; int c; printf("请输入有向图的顶点数:"); scanf("%d",&g.vexnum); i=g.vexnum*(g.vexnum-1); printf("请输入有向图的边数:"); scanf("%d",&g.arcnum); getchar(); printf("请依次输入有向图的各个顶点:"); for(i=0;i=0) { printf("输入的顶点重复,请重新输入\n"); i--; continue; 8 } g.vertices[i].data=c; g.vertices[i].firstarc=NULL; } for(k=0;kadjvex=j; p->nextarc=g.vertices[i].firstarc;//顶点i的链表 g.vertices[i].firstarc=p;//添加到最左边 } printf("\n有向图的邻接表创建成功\n\n"); return 1; } 9 3.2 深度优先遍历函数 函数名称:void dfs(ALGraph G,int cur,int* save,int size) 函数功能:实现从选定的顶点开始对有向图进行深度优先遍历,函数中g为当前要搜索的图,cur为当前搜索的顶点的下标,save是一个数组,用来保存搜索过的顶点,size为save数组的大小。在遍历中将遍历的顶点放入save中,当搜索到的顶点回到起点时,为找到回路,打印出有向图的回路。 函数的具体代码如下: void dfs(ALGraph G,int cur,int* save,int size) { int i; ArcNode *p=G.vertices[cur].firstarc; save[size]=cur; while(p) { if(save[0]==p->adjvex) { count++; printf("第%d条回路 ",count); for(i=0;i%d ",G.vertices[save[i]].data,G.vertices[save[i+1]].data); printf } printf("%d->%d\n",G.vertices[save[i]].data,G.vertices[save[0]]); } else if(flag[p->adjvex]==0) { flag[p->adjvex]=1; 10 dfs(G,p->adjvex,save,size+1); flag[p->adjvex]=0; } p=p->nextarc; } 11 4 程序测试及结果分析 4.1 程序测试及结果 (1)当输入有向图为4个顶点,5条弧时,有向图如下图所示: 1 2 3 4 图4.1.1 有向图1 图4.1.2程序测试图1 12 (2)当输入有向图为6个顶点,8条弧时,有向图如下: 1 2 3 6 5 4 图4.1.3 有向图2 图4.1.4 程序测试图2 13 (3)当输入有向图为5个顶点,4条弧时,此时有向图无回路,有向图如 下: 1 2 3 5 4 图4.1.5 有向图3 图4.1.6 程序测试图3 14 参考文献 [1] 严蔚敏,吴伟明. 数据结构(C语言版)[M]. 北京:清华大学出版社,2006 [2] 吕国英. 算法设计与分析[M]. 北京:清华大学出版社,2006 [3] 徐宝文,李志. C程序设计语音[M]. 北京:机械工业出版社,2004 15 附 录(关键部分程序清单) #include "stdafx.h" #include #include #include typedef struct ArcNode { int adjvex; // 该弧所指向的顶点的位置 struct ArcNode *nextarc; // 指向下一条弧的指针 }ArcNode; typedef struct VNode { int data; // 顶点信息 ArcNode *firstarc; // 指向第一条依附该顶点的弧 }VNode, AdjList[50]; typedef struct { AdjList vertices; int vexnum, arcnum; // 图的当前顶点数和弧数 }ALGraph; int flag[50]; //这个是标志顶点是否被搜索过,flag[1]=1 表示顶点1被搜索 过,否则没有被搜过过 int count; //回路条数 int locateALG(ALGraph g,int v) //v 是顶点的值,locateALG函数通 过v值,返回顶点v在 g的顶点数组的下标索引 { for(int i=0;i=0) 17 { printf("输入的顶点重复,请重新输入\n"); i--; continue; } g.vertices[i].data=c; g.vertices[i].firstarc=NULL; } //这里输入边信息 for(k=0;kadjvex=j; p->nextarc=g.vertices[i].firstarc;//顶点i的链表 g.vertices[i].firstarc=p;//添加到最左边 18 } printf("\n有向图的邻接表创建成功\n\n"); return 1; } //使用深度优先搜索方法找出回路 //g:当前要搜索的图 //cur:当前搜索的顶点的下标 //save数组: 保存搜索过的顶点 //size:save数组的大小 void dfs(ALGraph G,int cur,int* save,int size) { int i; ArcNode *p=G.vertices[cur].firstarc; //取得顶点的链接表 save[size]=cur; //保存搜索过的顶点 //遍历所有边 while(p) { //save[0]是开始顶点 //搜索到的顶点回到起点,找到回路,打印 if(save[0]==p->adjvex) { count++; printf("第%d条回路 ",count); for(i=0;i%d ",G.vertices[save[i]].data,G.vertices[save[i+1]].data); } 19 printf("%d->%d\n",G.vertices[save[i]].data,G.vertices[save[0]]); } //顶点没有被搜索过,搜索这个顶点 else if(flag[p->adjvex]==0) { flag[p->adjvex]=1; //标志已经搜索过 dfs(G,p->adjvex,save,size+1); flag[p->adjvex]=0; //搜索回来,取消标志 } p=p->nextarc; //下一条边 } } int main(void) { int save[50]; ALGraph g; int v; char sel; CreateADG(g); //创建有向图 do{ do{ printf("\n请输入开始顶点:");//输入开始顶点 scanf("%d",&v); v=locateALG(g,v); if(v<0) printf("\n没有找到顶点!\n\n"); }while(v<0); printf("\n"); 20 memset(flag,0,sizeof(flag)); //设置标志位,初始化所有顶点, 顶点全部没有访问过 flag[v]=1; //顶点v访问过 //开始搜索回路 count=0; dfs(g,v,save,0); printf("\n一共%d条回路\n\n",count); printf("是否继续?(Y/N)"); getchar(); scanf("%c",&sel); }while(sel!='n' && sel!='N'); return 0; } 21 课程设计: 本程序以C语言的相关知识为基础,通过对数据结构中邻接表和深度优先遍历的再次学习,成功的有C实现了求有向图的所有简单回路。从程序的编写来看,感觉这次自己真的学到了好多,又巩固了原来所学的知识, 当然在编写程序与调试程序的过程中也遇到了不少的问题,在与同学交流和查找相关资料的情况下也得到了解决,在这个算法中,最为核心的就是深度优先遍历了,再对这个算法的学习中遇上了不少问题,比如关于如何递归,在遍历了当前顶点之后回溯到原来的顶点继续遍历未遍历的顶点。 总之,经过本次专业课程设计,让我掌握了开发应用软件的基本流程,运用所学编程技能的基本技巧,也让我初步了解了软件设计的基本方法,提高进行工‎‎程设计的基本技能及分‎‎析、解决实际问题的能力,为以后毕业设计和工程实践等打下良好的基础。相信通过这次的课程设计,我对所学的《数据结构(C语言版)》和各种编程语言都有了一个全新的‎‎认识。我也会积极吸取本次课程设计的经验,继续研究数据结构和所学的各种编程语言。 指导教师评语: 指导教师(签字): 年 月 日 课程设计成绩 22
/
本文档为【数据结构-求有向图的所有简单回路】,请使用软件OFFICE或WPS软件打开。作品中的文字与图均可以修改和编辑, 图片更改请在作品中右键图片并更换,文字修改请直接点击文字进行修改,也可以新增和删除文档中的内容。
[版权声明] 本站所有资料为用户分享产生,若发现您的权利被侵害,请联系客服邮件isharekefu@iask.cn,我们尽快处理。 本作品所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用。 网站提供的党政主题相关内容(国旗、国徽、党徽..)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。

历史搜索

    清空历史搜索