图的遍历动态演示

图的遍历动态演示
图的遍历动态演示

图的遍历动态演示程序

摘要:图是一种复杂的数据结构,具有较高的学习难度。本文讲述了对图的动态演示程序的操作和程序的具体实现过程,使得我们对图的认识更深刻,学习更容易。本软件以Visual Studio 2008作为开发工具,使用邻接表法,用MFC类库实现了对图的可视化创建和图的遍历的动态演示。本文首先讲解了图的遍历动态演示程序的实现框架和设计思路,然后深入讲解了对图中结点和弧的创建、插入和删除,最后着重讲解了图的深度优先遍历和广度优先遍历动态演示的具体实现。

关键词:图; 遍历; 动态演示

The dynamic demonstrative program of traverse graph Abstract:Graph is a complex data structure, which is hard to learn. This thesis tells people the manipulate of the dynamic demonstrate of traverse graph and the specific realization progress of the program. This study give us a deeper understanding of graph, as well as make it easier to learn it. This software realizes the visual creation of graph and the dynamic demonstration of traverse graph by using adjacent table, MFC library and Visual Studio 2008. This thesis firstly explains the realization of the dynamic demonstrate of traverse graph program, the go into the depth of the creation, insertion, deleting of node and arc, at last explains emphatically the actual realization of the Depth-First traverse of graph and the Breadth-First traverse of graph.

Key Words:graph, traverse, dynamic demonstrative

目录

1 引言 (1)

1.1 开发背景 (1)

1.2 开发的目的以及意义 (1)

2 需求分析 (1)

2.1 功能概述 (1)

2.2 功能需求分析 (2)

2.2.1 结点的操作 (2)

2.2.2 弧的操作 (2)

2.2.3 自动生成图的支持 (2)

2.2.4 支持图的销毁 (3)

2.2.5 图的遍历类型 (3)

2.2.6 图的存储结构 (3)

2.2.7 图的遍历代码 (3)

2.2.8 支持图的遍历次序显示和中间辅助队列的进出队情况显示 (3)

2.2.9 支持对遍历速度的设置 (3)

2.2.10 支持暂停和单步 (3)

2.2.11 支持对图的实现代码的查看和运行 (4)

2.2.12 支持对版本和帮助的显示 (4)

3 总体设计 (4)

3.1 程序框架的搭建 (4)

3.1.1 工程项目的创建 (4)

3.1.2 窗口的显示 (4)

3.2 菜单的制作 (6)

3.2.1 创建图 (6)

3.2.2 设置演示速度 (8)

3.2.3 查看源代码的实现 (8)

3.2.4 运行此程序菜单的实现 (9)

3.2.5 打开此文件菜单和帮助菜单的实现 (10)

3.2.5 版本菜单的实现 (10)

3.2.6 退出菜单功能的实现 (10)

3.3图的创建和遍历核心算法的设计与实现 (10)

3.3.1 算法的设计 (10)

3.3.2 核心算法的实现 (16)

4 测试与总结 (28)

谢辞 (29)

参考文献 (30)

1 引言

在纷繁复杂的社会生活中,很多东西都涉及到图的应用问题。最早的图的应用可以追溯到18世纪伟大的数学家欧拉用图解决了著名的哥尼斯堡桥问题。目前,图的应用已经渗透到诸如电子线路分析、寻找最短路径、工程计划分析、人工智能、信息检索等领域。而图的遍历是运用图解决问题必须掌握的知识。

1.1 开发背景

社会生活中很多问题都涉及到“图”的知识,这些问题一般都比较复杂,比较难以解决,要解决这些问题,对“图”的学习是必须的。但目前对于“图”知识的讲解用得最多的是ppt演示,而ppt只能演示已经设计好的“图”,灵活性差,而且这些ppt的制作过程都比较繁琐。因此,设计一个能创建动态图,并且可以演示其遍历的软件非常重要。本次毕业设计我用MFC开发一个图的遍历动态演示程序,希望能让初学者能够更好、更容易地掌握图的知识。

1.2 开发的目的以及意义

为了让初学者更轻松地掌握“图”的知识,有必要进行本次毕业设计。本次的毕业设计是将书本上所学的理论知识与实际相结合,是对所学知识的一种检查,是对动手能力的一种锻炼,同时也是从学习走向真正开发的一个过渡,希望通过本次的毕业设计使自己在程序的开发和设计上有新的认识并能有所提高。

2 需求分析

2.1 功能概述

首先是对图类型的选择,图的类型分为有向图和无向图。其次是图的创建和销毁。图的创建包括对图结点和弧的添加、插入和删除,其中添加和插入可以和成一个功能,都是增加数据信息。这些功能的实现还必须在图形界面上显示出来,且用户能够方便

地进行操作。最后就是图的遍历。图的遍历分为深度优先遍历和广度优先遍历,选择不同的遍历方式运行时,根据代码的执行步骤及时的在界面上反应遍历到哪个结点和图存储结构上的动态显示。这里代码显示、图存储结构的显示和图的显示要同步起来。对于遍历时速度也需要进行设置。对于整个图的创建、遍历、销毁的代码实现,应该能够显示给用户看,而且还应该可以让用户感受一下该代码的运行效果。

2.2 功能需求分析

2.2.1 结点的操作

结点用圆和圆上的字符来表示,圆上的字符表示结点的名称。当选择创建结点,在绘图区域点击鼠标的时候,在绘图区域绘制一个结点,并且在图的数据结构中添加一个结点,还要保存结点的位置。结点在创建的时候应该保证其名称的唯一性。当选择删除结点,在绘图区点击一个结点的时候,首先要检测鼠标点击位置是否有结点,如果有,则把保存该结点位置的信息以及和该结点相关的弧的位置信息删掉,并且把该结点从图的数据结构中删除,然后重绘一下图。如果没有,则不做任何操作。

2.2.2 弧的操作

根据图类型的不同,弧的表示也不同。如果是有向图,则用一个箭头表示,箭头指向的是弧头,箭头的起始端是弧尾。如果是无向图,则用一条直线表示。当选择创建弧,在画图区域点击时,画一条直线或者一个箭头,并且在图的数据结构中添加一条弧,然后将弧的位置保存一下。弧的创建应该避免重复弧的产生。当选择删除弧,并且在画图区域点击时,先判断鼠标点击的位置是否存在一条弧,如果存在,则删除图数据结构中的选中的弧,并且删除保存的相应弧的位置信息,然后重绘一下图。

2.2.3 自动生成图的支持

有时为了图方便快捷,希望一键创建图,这时应该可以点击一个按钮生成整个图,图的生成就是结点和弧的创建过程,其实现原理和注意事项参照上面的结点的操作和弧的操作中创建结点和创建弧的部分。

2.2.4 支持图的销毁

当图的创建不是很满意的时候,可以点击清空按钮将图的结点位置信息和弧的位置信息清空,并且将图的数据结构销毁,然后清空绘图区域。

2.2.5 图的遍历类型

图的遍历分为深度优先遍历和广度优先遍历,程序对这两种方式都应该支持。选择不同的遍历方式,加载不同的初始化信息。

2.2.6 图的存储结构

图的遍历动态演示就是要动态地展示图是如何遍历其存储结构的。图遍历到哪里了,下一步应该访问哪个结点等都应该能准确地显示给用户。

2.2.7 图的遍历代码

图在遍历时,应该根据代码一步一步地遍历,动态地展示代码运行到哪里了同样可以比较直观地体现图的遍历的整个流程。图的动态显示和图存储结构的动态显示应该根据图的代码执行步骤来动态显示。

2.2.8 支持图的遍历次序显示和中间辅助队列的进出队情况显示

图在遍历过程中,应显示中间辅助队列的进队和出队的情况。图遍历完成后还要显示一下遍历结果,也就是这种遍历方式的遍历次序的显示。

2.2.9 支持对遍历速度的设置

图的遍历速度不能固定,用户可以根据个人喜好来设置图的遍历速度,以便更好地体验图的遍历的整个过程。

2.2.10 支持暂停和单步

当程序在执行遍历的时候,如果想仔细查看当前的各项情况,可以暂停遍历,参

看完成之后可以点击运行继续执行,也可以点击单步查看每一步的执行情况。

2.2.11 支持对图的实现代码的查看和运行

只看遍历的那部分代码有时候还不够,需要对图的创建等都有相应的了解,这时可以查看图的整个实现代码,并且运行该代码。

2.2.12 支持对版本和帮助的显示

如果想查看版本和帮助信息,可以点击相应的菜单项查看。

3 总体设计

3.1 程序框架的搭建

3.1.1 工程项目的创建

利用MFC的应用程序向导创建一个名称为GraphShow的对话框工程项目。由于涉及到很多绘图的内容,为了避免多次界面重绘带来的闪屏或者界面卡死等可能性问题,这里保持对话框不能调整大小的默认属性。

3.1.2 窗口的显示

如图1所示,此窗口的主体是向导帮我们生成的。首先我们删掉默认生成的一个Static Text控件和两个Button控件,然后向界面中添加三个Static Text控件、一个ListBox控件、两个Radio Button控件和三个Button控件(各个控件的属性如表1所示)。再者,我们添加一个Menu资源,设置好其中的各项,并把本窗体的Menu 属性设置为刚添加的Menu资源的ID。这样,我们就把窗体分为了这样几个区域:图的存储结构显示区域、图的显示区域、代码显示区域、遍历结果显示区域、菜单区域和其它按钮区域。图的存储结构显示区域由一个继承自CStatic类的CDrawLink类来控制,这个类拥有一个ALGraph结构体类型的成员;图的显示区域由CGraphDraw类来控制,这个类也是继承自CStatic;代码显示区域一个CListBox类型的变量关联;

遍历结果显示区域由继承自CStatic类的CShowResult类来控制;整个界面由CGraphShowDlg类来管理,它继承自CDialog类,并且拥有一个ALGraph类型的成员。当按下执行按钮的时候,开启一个线程,这个线程遍历图的同时设置List Box中选中的行、画图中被访问的结点和图存储结构中被访问的结点。基本做到代码选中行的意思和图、存储结构的访问情况相符合。

图1 图的遍历

表格 1图的遍历窗口上各控件属性

控件类型控件ID控件Caption 其它

Static Text IDC_STATIC_LINK

Static Text IDC_STATIC_GRAPH

List Box IDC_LIST

Static Text IDC_STATIC_ORDER

Radio Button IDC_RADIO_DFS 深度优先遍历Group属性为True Radio Button IDC_RADIO_BFS 广度优先遍历

Button IDC_BUTTON_RUN 执行

Button IDC_BUTTON_STEP 单步执行

Button IDC_BUTTON_PAUSE 暂停

3.2 菜单的制作

向工程中添加菜单资源,其资源ID为IDR_MENU。然后添加“操作”和“关于”菜单项,分别有:创建图、设置演示速度、查看源代码、退出、版本和帮助这几个子菜单项。将此菜单加入到主界面中。如图2所示。

图2 主界面菜单

向工程添加菜单资源,其ID为IDR_MENU_CODE。然后添加“操作”菜单项,其内容分别是:运行此程序、打开此文件和退出。将此菜单加入到查看源代码界面中。如图3所示。

图 3 查看源代码界面菜单

3.2.1 创建图

图4为创建图的界面。要绘制这个对话框,先向工程中添加一个Dialog资源,Dialog资源的ID为IDD_DIALOG_CREATE,Caption为“创建图”。然后向Dialog中添加两个Group Box控件、六个Radio Button控件、一个Static Text控件和三个Button控件,它们的属性设置如表2所示。

这个窗口所有功能的代码实现在CGraphCreate、 CGraphDraw、ALGraph、VNode、ArcNode这几个类或结构体中。其中ArcNode是表示弧的结构体,VNode是表示结点的结构体,ALGraph是表示邻接表法存储图的结构体。CGraphDraw是一个继承自CStatic的类,它控制画图区域,它拥有一个ALGraph结构体类型的成员。CGraphCreate是控制整个界面的类,它拥有CGraphDraw类型的成员。界面中的两组单选按钮分别CGraphCreate类的两个成员变量关联,分别是m_nType和m_nCreate,

通过向CGraphDraw类传递这两个值来控制图的类型和许可的操作。

图4 创建图

表格 2创建图对话框上各控件属性

控件类型控件ID控件Caption 其它

Group Box 图的类型

Radio Button IDC_RADIO_DG 有向图Group属性为True Radio Button IDC_RADIO_AG 无向图

Static Text IDC_STATIC_DRAW

Group Box

Radio Button IDC_RADIO_CREATENODE 创建结点Group属性为True Radio Button IDC_RADIO_ CREATEARC 创建弧

Radio Button IDC_RADIO_ DELETENODE 删除结点

Radio Button IDC_RADIO_DELETEARC 删除弧

Button IDC_BUTTON_AUTO 自动生成图

Button IDC_BUTTON_CLEAN 清空

Button IDC_BUTTON_AUTOCREATE 确定

3.2.2 设置演示速度

首先向工程中添加对话框资源,设置其ID为IDD_DIALOG_SETSPEED,Caption 为“设置演示速度”。然后向这个对话框中加入一个Group Box控件、两个Static Text 控件、一个Slider控件和一个Button控件。最后设置Group Box的Caption为“设置速度”,两个Static Text的Caption分别为“慢”和“快”,Slider的ID为IDC_SLIDER1,Button的Caption为“确定”、ID为IDC_BUTTON_SETSPEED。结果如图4。把这个对话框和CSetSpeed类关联起来,把Slider控件和CSetSpeed类的一个整型成员变量m_nCur和一个CSliderCtrl类型的成员变量m_ctrlSpeed关联起来。在初始化对话框的时候,通过调用m_ctrlSpeed.SetRange(int,int)来设置滚动条的范围,调用m_ctrl.SetPos(int)来设置滚动条的位置。当用鼠标拖动滚动条的时候会产生WM_HSCROLL消息。在这个消息的处理里面获得滚动条的位置,给m_nCur赋值,这个值穿给主对话框对应的类后,经过一定的计算就可以控制演示的速度了。

图5 演示速度设置

3.2.3 查看源代码的实现

首先向工程中添加一个对话框资源,其ID为IDD_DIALOG_RESOURCE,Caption 为“源程序”。然后在对话框中添加一个List Box控件,设置其ID为IDC_LIST_RESOURCE,Horizontal Scroll设置为True。并且把ID为IDR_MENU_CODE 的菜单添加到对话框的中。把List Box和一个CListBox类型的对象m_cltbResoure 关联起来。在对话框初始化的时候读取code.c这个文件,将其中的内容加入到List

Box控件中。

图6 源代码查看

3.2.4 运行此程序菜单的实现

点击此菜单,调用CreateProcess函数创建一个子进程,这个子进程打开一个控制台窗口,该控制台可以实现对结点和弧的添加、插入和删除操作,以及图的深度优先遍历和广度优先遍历。如图7所示。

图7 源代码执行

3.2.5 打开此文件菜单和帮助菜单的实现

点击菜单的时候,调用ShellExecuteEx让电脑上的软件打开相应的文件。

3.2.5 版本菜单的实现

由于使用应用程序向导创建MFC Dialog类型的应用程序的时候,默认会插入一个ID为IDD_ABOUTBOX的对话框。该对话框关联的类为CAboutDlg,我们在该对话框内添加几个Static Text来实现对版本信息的显示。

3.2.6 退出菜单功能的实现

当点击退出菜单的时候,调用EndDialog关闭对话框,进而关闭整个程序。

3.3图的创建和遍历核心算法的设计与实现

3.3.1 算法的设计

图的存储,可以用邻接表法表示图。

邻接表是图的一种链式存储结构。在邻接表中,对图中每个顶点简历一个单链表,

第i个单链表中的结点表示依附于顶点v

i 的边(对有向图是以顶点v

i

为尾的弧)。每

个结点由3个域组成,其中邻接点域指示与顶点v

i

邻接的点在图中的位置,链域指

示下一条边或弧的结点;数据域存储和边或弧相关的信息,如权值等。每个链表上附设一个表头结点。在表头结点中,除了设有链域指向链表中第一个结点之外,还设有

存储顶点v

i

的名或其他有关信息的数据域。如下图所示

表结点头结点

这些表头结点(可以链相接)通常以顺序结构的形式存储,以便随机访问任一顶点的

链表。

图的遍历是从图中某一顶点触发访遍图中其余顶点,且使每一个顶点仅被访问一次。通常有两条遍历图的路径:深度优先遍历和广度优先遍历。

图的深度优先遍历类似于书的先根遍历,是树的先根遍历的推广。假设初始化状态是图中所有顶点未曾被访问,则深度优先遍历可从图中某个顶点v出发,访问此顶点,然后依次从v的未被访问的邻接点出发深度优先遍历图,直至图中所有和v有路径相通的顶点都被访问到;若此时图中尚有顶点未被访问,则另选图中一个未曾被访问的顶点作起始点,重复上述过程,直至图中所有顶点都被访问到为止。

图的广度优先遍历类似于树的按层次遍历的过程。假设从图中顶点v出发,在访问了v之后依次访问v的各个未曾访问过的邻接点,然后分别从这些邻接点出发依次访问它们的邻接点,并使“先被访问的顶点的邻接点”先于“后被访问的顶点的邻接点”被访问,直至图中所有已被访问的顶点的邻接点都被访问到。若此时图中尚有顶点未被访问,则另选图中一个未曾被访问的顶点作起始点,重复上述过程,直至图中所有顶点都被访问到为止。换句话说,广度优先遍历的过程是以v为起始点,由近至远,依次访问和v有路径相通且路径长度为1,2,…的顶点。

由于本次毕业设计需要动态的演示图的遍历过程,这涉及到绘图的问题。因此,在图的结点和弧创建的时候都需要记录他们的位置,并且设置他们的访问标志为未被访问。当图中的结点和弧被删除的时候,需要删除对应的结点和弧,并且把保存的对应的位置和访问信息重置。当图中的结点和弧被访问的时候要设置他们的访问标志为已经被访问。

在创建节点的时候,其算法流程如图8所示。

图 8 创建结点

当选择删除结点时,其具体的处理流程路图9所示。

图 9 结点的删除

在判断鼠标点击是否命中结点的时候,需要遍历所有结点,求出每一个结点的圆

心到鼠标点击位置的长度,其具体的计算公式为:

长度L = sqrt(pow(y2 – y1, 2) + pow(x2 – x1, 2))如果长度小于结点圆的半径,则为命中了该节点。

在创建弧的时候,具体的操作流程如图10所示。

图 10 创建弧

创建弧时,为了画得好看,并不是从两个节点的圆心画一条线,而是从两圆心的连线与圆周的交点处画线,这两个坐标的具体求解方法如图11.

图 11 求两结点圆心连线与圆周交点辅助图

假设两个圆的圆心坐标为A(x1,y1)、B(x2,y2),则AB直线的长度为:|AB|=sqrt(pow(x2-x1,2)+pow(y2-y1,2))利用相似三角形求解,可知(y2-y1)/y=|AB|/R,求解得出y=abs(y2-y1)*R/sqrt(pow(x2-x1,2)+pow(y2-y1,2)),同理可以得出x=abs(x2-x1)*R/sqrt(pow(x2-x1,2)+pow(y2-y1,2))。则与两圆周交点的坐标为:

(x2>x1?x1+x:x1-x,y2>y1?y1+y:y1-y)

(x1>x2?x2+x:x2-x,y1>y2?y2+y:y2-y)

然后以这两个交点为起始点画直线或者画箭头即可。至于画箭头的数学推导,这里就不详细说明,只是在算法实现里面给出实现代码。

删除弧的处理流程如图11所示。

图 11 删除弧

其中,删除弧的时候要判断鼠标点击时是否命中弧,其具体的算法为:遍历每一条弧,根据弧头和弧尾的坐标,进行如下三种情况下的判定:

当弧的两个结点位置的x坐标相差不到2个像素的时候,可以规划一个矩形区域,鼠标点击在这个矩形区域即为命中。这个矩形区域的left值为两个结点中任意一个结点的x值减3,right值为该任意结点的x值加3,top值为结点中较小的那个y值,bottom为结点中较大的那个y值。

当弧的两个结点位置的y坐标相差不到2个像素的时候,可以规划一个矩形区域,鼠标点击在这个矩形区域即为命中。这个矩形区域的top值为两个结点中任意一个结点的y值减3,bottom值为该任意结点的y值加3,left值为结点中较小的那个x值,right为结点中较大的那个x值。

排除上面两种情况后,应该这么判定弧是否被选中:首先根据弧的弧头和弧尾的坐标写出这两点之前的直线方程y = (y2 – y1)*(x – x1)/(x2 – x1)。把鼠标点击时位置的x坐标值代入到该方程中,如果得到的y值和鼠标点击时位置的y值差距在3个像素以内,并且鼠标点击的位置在弧头和弧尾组成的矩形区域内,则为命中弧。

3.3.2 核心算法的实现

图的遍历动态演示程序主要分为图的创建和图的遍历。

用邻接表法实现图,数据结构为:

#define MAX_VERTEX_NUM 26

typedef enum{DG,AG,DN,AN} GraphKind;

typedef struct ArcNode

{

int adjvex;//该弧所指向的顶点的位置

struct ArcNode *nextarc;//指向下一条弧的指针

InfoType *info;//该弧相关信息的指针

}ArcNode;

typedef struct VNode

{

VertexType data;//顶点信息

ArcNode *firstarc;//指向第一条依附该顶点的弧的指针

}VNode;

typedef struct ALGraph

{

vector vertices;

int vexnum,arcnum;// 图的当前顶点数和弧数

int kind;//图的种类标志

}ALGraph;

创建结点的具体代码实现为:

void ALGraph::CreateNode()

{

VNode node;

if (vertices.size() == 0)//图中没有结点,则将结点名字标记为A。

{

node.data = "A";

}

else//图中有结点则将名字标记为上个结点的名字的ascii码加1得到的字符{

node.data = vertices.back().data.at(0);

node.data.at(0)++;

}

vertices.push_back(node);//将结点加入到图中

}

创建弧的具体代码实现为:

void ALGraph::CreateArc(int BegPos, int EndPos)

{

ArcNode *arc = NULL;

arc = new ArcNode();//新建一条弧

arc->adjvex = EndPos;//设置该弧指向EndPo位置的结点

arc->info = NULL;//不为其设置权值。

//将本弧插入到位序为BegPos结点链表的前面

arc->nextarc = vertices.at(BegPos).firstarc; vertices.at(BegPos).firstarc = arc; }

删除结点的具体代码实现为:

void ALGraph::DeleteNode(VertexType v)

{

int i, j;

ArcNode *p = NULL, *q = NULL;

j = LocateVex(v);//获取v结点的位序

if (j < 0)

{

return;

}

p = vertices.at(j).firstarc;

while (p)//遍历v结点的出度链表,删除链接的弧

{

q = p;

p = p->nextarc;

if (kind / 2)

{

free(q->info);

}

free(q);

arcnum--;

}

vexnum--;//结点数减少1

for (i = j; i < vexnum; i++)//把要删除结点之后的数据往前移动

{

vertices.at(i) = vertices.at(i + 1);

}

vertices.erase(vertices.end() - 1);//移动后删除最后面的元素

//遍历整个图,删除和v结点有入度关系的弧。

for (i = 0; i < vexnum; i++)

{

p = vertices.at(i).firstarc;

while (p)

{

if (p->adjvex == j)

图的深度广度优先遍历操作代码

一、实验目的 1.掌握图的各种存储结构,特别要熟练掌握邻接矩阵和邻接表存储结构; 2.遍历是图各种应用的算法的基础,要熟练掌握图的深度优先遍历和宽度优先遍历算法,复习栈和队列的应用; 3.掌握图的各种应用的算法:图的连通性、连通分量和最小生成树、拓扑排序、关键路径。 二、实验内容 实验内容1**图的遍历 [问题描述] 许多涉及图上操作的算法都是以图的遍历为基础的。写一个程序,演示在连通无向图上遍历全部顶点。 [基本要求] 建立图的邻接表的存储结构,实现无向图的深度优先遍历和广度优先遍历。以用户指定的顶点为起点,分别输出每种遍历下的顶点访问序列。 [实现提示] 设图的顶点不超过30个,每个顶点用一个编号表示(如果一个图有N个顶点,则它们的编号分别为1,2,…,N)。通过输入图的全部边输入一个图,每条边是两个顶点编号对,可以对边依附顶点编号的输入顺序作出限制(例如从小到大)。 [编程思路] 首先图的创建,采用邻接表建立,逆向插入到单链表中,特别注意无向是对称插入结点,且要把输入的字符在顶点数组中定位(LocateVex(Graph G,char *name),以便后来的遍历操作,深度遍历算法采用递归调用,其中最主要的是NextAdjVex(Graph G, int v, int w);FirstAdjVex ()函数的书写,依次递归下去,广度遍历用队列的辅助。 [程序代码] 头文件: #include #include #define MAX_VERTEX_NUM 30 #define MAX_QUEUE_NUMBER 30 #define OK 1 #define ERROR 0 #define INFEASIBLE -1

数据结构课程设计图的遍历和生成树求解

数学与计算机学院 课程设计说明书 课程名称: 数据结构与算法课程设计 课程代码: 6014389 题目: 图的遍历和生成树求解实现 年级/专业/班: 学生姓名: 学号: 开始时间: 2012 年 12 月 09 日 完成时间: 2012 年 12 月 26 日 课程设计成绩: 指导教师签名:年月日

目录 摘要 (3) 引言 (4) 1 需求分析 (5) 1.1任务与分析 (5) 1.2测试数据 (5) 2 概要设计 (5) 2.1 ADT描述 (5) 2.2程序模块结构 (7) 软件结构设计: (7) 2.3各功能模块 (7) 3 详细设计 (8) 3.1结构体定义 (19) 3.2 初始化 (22) 3.3 插入操作(四号黑体) (22) 4 调试分析 (22) 5 用户使用说明 (23) 6 测试结果 (24) 结论 (26)

摘要 《数据结构》课程主要介绍最常用的数据结构,阐明各种数据结构内在的逻辑关系,讨论其在计算机中的存储表示,以及在其上进行各种运算时的实现算法,并对算法的效率进行简单的分析和讨论。进行数据结构课程设计要达到以下目的: ?了解并掌握数据结构与算法的设计方法,具备初步的独立分析和设计能力; ?初步掌握软件开发过程的问题分析、系统设计、程序编码、测试等基本方法和技能; ?提高综合运用所学的理论知识和方法独立分析和解决问题的能力; 训练用系统的观点和软件开发一般规范进行软件开发,培养软件工作者所应具备的科学的工作方法和作风。 这次课程设计我们主要是应用以前学习的数据结构与面向对象程序设计知识,结合起来才完成了这个程序。 因为图是一种较线形表和树更为复杂的数据结构。在线形表中,数据元素之间仅有线性关系,每个元素只有一个直接前驱和一个直接后继,并且在图形结构中,节点之间的关系可以是任意的,图中任意两个数据元素之间都可能相关。因此,本程序是采用邻接矩阵、邻接表、十字链表等多种结构存储来实现对图的存储。采用邻接矩阵即为数组表示法,邻接表和十字链表都是图的一种链式存储结构。对图的遍历分别采用了广度优先遍历和深度优先遍历。 关键词:计算机;图;算法。

图的遍历实现课程设计-数据结构-程序-图

数据结构课程设计 设计说明书 图的遍历的实现 学生姓名英茜 学号1118064033 班级网络1101班 成绩 指导教师申静 数学与计算机科学学院 2014年1 月4日

课程设计任务书 2013—2014学年第一学期 课程设计名称:数据结构课程设计 课程设计题目:图的遍历实现 完成期限:自2013年12月23日至2014年1月4日共 2 周 设计内容: 1. 任务说明 (1)采用邻接表存储结构创建一个图; (2)编程实现图的深度优先搜索(或广度优先搜索)遍历算法; (3) 输出遍历结果; (4) 给定具体数据调试程序。 2.要求 1)问题分析和任务定义:根据设计题目的要求,充分地分析和理解问题,明确问题要求做什么? 2)逻辑设计:写出抽象数据类型的定义,各个主要模块的算法,并画出模块之间的调用关系图; 3)详细设计:定义相应的存储结构并写出各函数的伪码算法。 4)程序编码:把详细设计的结果进一步求精为程序设计语言程序。 5)程序调试与测试:采用自底向上,分模块进行,即先调试低层函数。 6)结果分析:程序运行结果包括正确的输入及其输出结果和含有错误的输入及其输出结果。算法的时间、空间复杂性分析; 7)编写课程设计报告。 3. 参考资料 指导教师:申静教研室负责人:余冬梅 课程设计评阅

摘要 针对图问题中如何更好地实现图的遍历问题,以无向图为例,分别采用广度优先遍历和深度优先遍历的算法实现对各节点的遍历,以VC++为开发环境进行系统的设计和实现,其运行结果表明,系统能很好地完成遍历后节点的输出,实现了遍历的目的,系统界面友好,可操作性强。 关键词:数据结构;存储结构;邻接矩阵

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

数据结构实验报告 实验:图的遍历 一、实验目的: 1、理解并掌握图的逻辑结构和物理结构——邻接矩阵、邻接表 2、掌握图的构造方法 3、掌握图的邻接矩阵、邻接表存储方式下基本操作的实现算法 4、掌握图的深度优先遍历和广度优先原理 二、实验内容: 1、输入顶点数、边数、每个顶点的值以及每一条边的信息,构造一个无向图G,并用邻接矩阵存储改图。 2、输入顶点数、边数、每个顶点的值以及每一条边的信息,构造一个无向图G,并用邻接表存储该图 3、深度优先遍历第一步中构造的图G,输出得到的节点序列 4、广度优先遍历第一部中构造的图G,输出得到的节点序列 三、实验要求: 1、无向图中的相关信息要从终端以正确的方式输入; 2、具体的输入和输出格式不限; 3、算法要具有较好的健壮性,对错误操作要做适当处理; 4、程序算法作简短的文字注释。 四、程序实现及结果: 1、邻接矩阵: #include #include #define VERTEX_MAX 30 #define MAXSIZE 20 typedef struct { int arcs[VERTEX_MAX][VERTEX_MAX] ; int vexnum,arcnum; } MGraph; void creat_MGraph1(MGraph *g) { int i,j,k; int n,m; printf("请输入顶点数和边数:"); scanf("%d%d",&n,&m); g->vexnum=n; g->arcnum=m; for (i=0;iarcs[i][j]=0;

图的遍历实验报告

实验四:图的遍历 题目:图及其应用——图的遍历 班级:姓名:学号:完成日期: 一.需求分析 1.问题描述:很多涉及图上操作的算法都是以图的遍历操作为基础的。试写一个程序,演示在连通的无向图上访问全部结点的操作。 2.基本要求:以邻接表为存储结构,实现连通无向图的深度优先和广度优先遍历。以用户指定的结点为起点,分别输出每种遍历下的结点访问序列和相应生成树的边集。 3.测试数据:教科书图7.33。暂时忽略里程,起点为北京。 4.实现提示:设图的结点不超过30个,每个结点用一个编号表示(如果一个图有n个结点,则它们的编号分别为1,2,…,n)。通过输入图的全部边输入一个图,每个边为一个数对,可以对边的输入顺序作出某种限制,注意,生成树的边是有向边,端点顺序不能颠倒。 5.选作内容: (1).借助于栈类型(自己定义和实现),用非递归算法实现深度优先遍历。 (2).以邻接表为存储结构,建立深度优先生成树和广度优先生成树,再按凹入表或树形打印生成树。 二.概要设计 1.为实现上述功能,需要有一个图的抽象数据类型。该抽象数据类型的定义为: ADT Graph { 数据对象V:V是具有相同特性的数据元素的集合,称为顶点集。 数据关系R: R={VR} VR={ | v,w v且P(v,w),表示从v到w得弧,谓词P(v,w)定义了弧的意义或信息} } ADT Graph 2.此抽象数据类型中的一些常量如下: #define TRUE 1 #define FALSE 0 #define OK 1 #define max_n 20 //最大顶点数 typedef char VertexType[20]; typedef enum{DG, DN, AG, AN} GraphKind; enum BOOL{False,True}; 3.树的结构体类型如下所示:

数据结构实验---图的储存与遍历

数据结构实验---图的储存与遍历

学号: 姓名: 实验日期: 2016.1.7 实验名称: 图的存贮与遍历 一、实验目的 掌握图这种复杂的非线性结构的邻接矩阵和邻接表的存储表示,以及在此两种常用存储方式下深度优先遍历(DFS)和广度优先遍历(BFS)操作的实现。 二、实验内容与实验步骤 题目1:对以邻接矩阵为存储结构的图进行DFS 和BFS 遍历 问题描述:以邻接矩阵为图的存储结构,实现图的DFS 和BFS 遍历。 基本要求:建立一个图的邻接矩阵表示,输出顶点的一种DFS 和BFS 序列。 测试数据:如图所示 题目2:对以邻接表为存储结构的图进行DFS 和BFS 遍历 问题描述:以邻接表为图的存储结构,实现图的DFS 和BFS 遍历。 基本要求:建立一个图的邻接表存贮,输出顶点的一种DFS 和BFS 序列。 测试数据:如图所示 V0 V1 V2 V3 V4 三、附录: 在此贴上调试好的程序。 #include #include #include V0 V1 V4 V3 V2 ??? ? ??? ? ????????=010000000101010 1000100010A 1 0 1 0 3 3 4

#define M 100 typedef struct node { char vex[M][2]; int edge[M ][ M ]; int n,e; }Graph; int visited[M]; Graph *Create_Graph() { Graph *GA; int i,j,k,w; GA=(Graph*)malloc(sizeof(Graph)); printf ("请输入矩阵的顶点数和边数(用逗号隔开):\n"); scanf("%d,%d",&GA->n,&GA->e); printf ("请输入矩阵顶点信息:\n"); for(i = 0;in;i++) scanf("%s",&(GA->vex[i][0]),&(GA->vex[i][1])); for (i = 0;in;i++) for (j = 0;jn;j++) GA->edge[i][j] = 0; for (k = 0;ke;k++) { printf ("请输入第%d条边的顶点位置(i,j)和权值(用逗号隔开):",k+1); scanf ("%d,%d,%d",&i,&j,&w); GA->edge[i][j] = w; } return(GA); } void dfs(Graph *GA, int v) { int i; printf("%c%c\n",GA->vex[v][0],GA->vex[v][1]); visited[v]=1;

数据结构图的遍历

#include"stdlib.h" #include"stdio.h" #include"malloc.h" #define INFINITY 32767 #define MAX_VERTEX_NUM 20 typedef enum{FALSE,TRUE}visited_hc; typedef enum{DG,DN,UDG,UDN}graphkind_hc; typedef struct arccell_hc {int adj; int*info; }arccell_hc,adjmatrix_hc[MAX_VERTEX_NUM][MAX_VERTEX_NUM]; typedef struct {char vexs[MAX_VERTEX_NUM]; adjmatrix_hc arcs; int vexnum,arcnum; graphkind_hc kind; }mgraph_hc; typedef struct arcnode_hc {int adjvex; struct arcnode_hc *nextarc; int*info; }arcnode_hc; typedef struct vnode_hc {char data; arcnode_hc *firstarc; }vnode_hc,adjlist_hc[MAX_VERTEX_NUM]; typedef struct {adjlist_hc vertices; int vexnum,arcnum; graphkind_hc kind; }algraph_hc; int locatevex_hc(mgraph_hc*g,char v) {int i,k=0; for(i=0;ivexnum;i++) if(g->vexs[i]==v){k=i;i=g->vexnum;} return(k);}

数据结构课程设计-图的遍历和构建

图(Graph)是一种复杂的非线性结构。图可以分为无向图、有向图。若将图的每条边都赋上一个权,则称这种带权图网络。在人工智能、工程、数学、物理、化学、计算机科学等领域中,图结构有着广泛的应用。在图结构中,对结点(图中常称为顶点)的前趋和后继个数都是不加以限制的,即结点之间的关系是任意的。图中任意两个结点之间都可能相关。图有两种常用的存储表示方法:邻接矩阵表示法和邻接表表示法。在一个图中,邻接矩阵表示是唯一的,但邻接表表示不唯一。在表示的过程中还可以实现图的遍历(深度优先遍历和广度优先遍历)及求图中顶点的度。当然对于图的广度优先遍历还利用了队列的五种基本运算(置空队列、进队、出队、取队头元素、判队空)来实现。这不仅让我们巩固了之前学的队列的基本操作,还懂得了将算法相互融合和运用。

第一章课程设计目的 (3) 第二章课程设计内容和要求 (3) 2.1课程设计内容 (3) 2.1.1图的邻接矩阵的建立与输出 (3) 2.1.2图的邻接表的建立与输出 (3) 2.1.3图的遍历的实现 (4) 2.1.4 图的顶点的度 (4) 2.2 运行环境 (4) 第三章课程设计分析 (4) 3.1图的存储 (4) 3.1.1 图的邻接矩阵存储表示 (4) 3.1.2 图的邻接表存储表示 (5) 3.2 图的遍历 (5) 3.2.1 图的深度优先遍历 (5) 3.2.2 图的广度优先遍历 (6) 3.3图的顶点的度 (7) 第四章算法(数据结构)描述 (7) 4.1 图的存储结构的建立。 (7) 4.1.1 定义邻接矩阵的定义类型 (7) 4.1.2定义邻接表的边结点类型以及邻接表类型 (7) 4.1.3初始化图的邻接矩阵 (8) 4.1.4 初始化图的邻接表 (8) 4.2 图的遍历 (8) 4.2.1 深度优先遍历图 (8) 4.2.2 广度优先遍历图 (9) 4.3 main函数 (9) 4.4 图的大致流程表 (10) 第五章源代码 (10) 第六章测试结果 (20) 第七章思想总结 (21) 第八章参考文献 (22)

数据结构课程设计之图的遍历和生成树求解

##大学 数据结构课程设计报告题目:图的遍历和生成树求解 院(系):计算机工程学院 学生: 班级:学号: 起迄日期: 2011.6.20 指导教师:

2010—2011年度第 2 学期 一、需求分析 1.问题描述: 图的遍历和生成树求解实现 图是一种较线性表和树更为复杂的数据结构。在线性表中,数据元素之间仅有线性关系,每个数据元素只有一个直接前驱和一个直接后继;在树形结构中,数据元素之间有着明显的层次关系,并且每一层上的数据元素可能和下一层中多个元素(及其孩子结点)相关但只能和上一层中一个元素(即双亲结点)相关;而在图形结构中,节点之间的关系可以是任意的,图中任意两个数据元素之间都可能相关。 生成树求解主要利用普利姆和克雷斯特算法求解最小生成树,只有强连通图才有生成树。 2.基本功能 1) 先任意创建一个图; 2) 图的DFS,BFS的递归和非递归算法的实现 3) 最小生成树(两个算法)的实现,求连通分量的实现 4) 要求用邻接矩阵、邻接表等多种结构存储实现 3.输入输出

输入数据类型为整型和字符型,输出为整型和字符 二、概要设计 1.设计思路: a.图的邻接矩阵存储:根据所建无向图的结点数n,建立n*n的矩阵,其中元素全是无穷大(int_max),再将边的信息存到数组中。其中无权图的边用1表示,无边用0表示;有全图的边为权值表示,无边用∞表示。 b.图的邻接表存储:将信息通过邻接矩阵转换到邻接表中,即将邻接矩阵的每一行都转成链表的形式将有边的结点进行存储。 c.图的广度优先遍历:假设从图中的某个顶点v出发,在访问了v之后依次访问v的各个未曾访问过的邻接点,然后再访问此邻接点的未被访问的邻接点,并使“先被访问的顶点的邻接点”先于“后被访问的顶点的邻接点”被访问,直至图中所有已被访问的顶点的邻接点都被访问到。若此时图中还有未被访问的,则另选未被访问的重复以上步骤,是一个非递归过程。 d.图的深度优先遍历:假设从图中某顶点v出发,依依次访问v的邻接顶点,然后再继续访问这个邻接点的系一个邻接点,如此重复,直至所有的点都被访问,这是个递归的过程。 e.图的连通分量:这是对一个非强连通图的遍历,从多个结点出发进行搜索,而每一次从一个新的起始点出发进行搜索过程中得到的顶点访问序列恰为其连通分量的顶点集。本程序利用的图的深度优先遍历算法。 2.数据结构设计: ADT Queue{ 数据对象:D={a i | a i ∈ElemSet,i=1,2,3……,n,n≥0} 数据关系:R1={| a i-1 ,a i ∈D,i=1,2,3,……,n} 基本操作: InitQueue(&Q) 操作结果:构造一个空队列Q。 QueueEmpty(Q) 初始条件:Q为非空队列。 操作结果:若Q为空队列,则返回真,否则为假。 EnQueue(&Q,e) 初始条件:Q为非空队列。 操作结果:插入元素e为Q的新的队尾元素。 DeQueue(&Q,e) 初始条件:Q为非空队列。 操作结果:删除Q的队头元素,并用e返回其值。}ADT Queue

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

实验项目名称:图的遍历 一、实验目的 应用所学的知识分析问题、解决问题,学会用建立图并对其进行遍历,提高实际编程能力及程序调试能力。 二、实验容 问题描述:建立有向图,并用深度优先搜索和广度优先搜素。输入图中节点的个数和边的个数,能够打印出用邻接表或邻接矩阵表示的图的储存结构。 三、实验仪器与设备 计算机,Code::Blocks。 四、实验原理 用邻接表存储一个图,递归方法深度搜索和用队列进行广度搜索,并输出遍历的结果。 五、实验程序及结果 #define INFINITY 10000 /*无穷大*/ #define MAX_VERTEX_NUM 40 #define MAX 40 #include #include #include #include

typedef struct ArCell{ int adj; }ArCell,AdjMatrix[MAX_VERTEX_NUM][MAX_VERTEX_NUM]; typedef struct { char name[20]; }infotype; typedef struct { infotype vexs[MAX_VERTEX_NUM]; AdjMatrix arcs; int vexnum,arcnum; }MGraph; int LocateVex(MGraph *G,char* v) { int c = -1,i; for(i=0;ivexnum;i++) if(strcmp(v,G->vexs[i].name)==0) { c=i; break;} return c;} MGraph * CreatUDN(MGraph *G)//初始化图,接受用户输入{ int i,j,k,w; char v1[20],v2[20]; printf("请输入图的顶点数,弧数:"); scanf("%d%d",&G->vexnum,&G->arcnum);

数据结构课程设计报告(图的遍历)

中南大学 课程设计报告 题目数据结构课程设计学生姓名 指导教师漆华妹 学院信息科学与工程学院专业班级 学号 完成时间 2011年07月

目录 第一章、需求分析 (2) 第二章、概要设计 (2) 2.1设定图的抽象数据类型 (2) 2.2设定队列的抽象数据类型 (3) 2.3本程序包含的功能模块 (3) 第三章、详细设计 (3) 3.1顶点、边和图的类型 (6) 3.2队列类型 (8) 3.3主程序和其他伪码算法 (9) 第四章、调试分析 (9) 第五章、用户手册 (9) 第六章、测试结果 (10) 第七章、心得体会 (10) 附:源程序代码 (11)

图遍历的演示 题目:试设计一个程序,演示在连通的无向图上访问全部结点的操作 第一章、需求分析 1、以邻接多重表为存储结构; 2、实现连通和非连通的无向图的深度优先和广度优先遍历; 3、要求利用栈实现无向图的深度优先遍历; 4、以用户指定的结点为起点,分别输出每种遍历下的结点访问序列和生成树的边集; 5、用凹入表打印生成树; 6、求出从一个结点到另外一个结点,但不经过另外一个指定结点的所有简单路径;6、本程序用C语言编写,在C-Free3.5环境下通过。 第二章、概要设计 1、设定图的抽象数据类型: ADT Graph{ 数据对象V:V是具有相同特性的数据元素的集合,称为点集. 数据关系R: R={VR} VR={(v,w)|v,w属于V,(v,w)表示v和w之间存在的路径} 基本操作P: CreatGraph(&G,V,VR) 初始条件:V是图的顶点集,VR是图中弧的集合. 操作结果:按V和VR是定义构造图G. DestroyGraph(&G) 初始条件:图G存在 操作结果:销毁图G LocateVex(G,u) 初始条件: 图G存在,u和G中顶点有相同的特征 操作结果:若图G中存在顶点u,则返回该顶点在图中的位置;否则返回其他信息GetVex(G,v) 初始条件: 图G存在,v是G中顶点 操作结果:返回v的值 FirstAjvex(G,v) 初始条件: 图G存在,v是G中顶点 操作结果:返回v的第一个邻接顶点,若顶在图中没有邻接顶点,则返回为空 NextAjvex(G,v,w) 初始条件: 图G存在,v是G中顶点,w是v的邻接顶点 操作结果:返回v的下一个邻接顶点,若w是v的最后一个邻接顶点,则返回空DeleteVexx(&G,v) 初始条件: 图G存在,v是G中顶点 操作结果:删除顶点v已经其相关的弧 DFSTraverse(G,visit()) 初始条件: 图G存在,visit的顶点的应用函数

数据结构 图的存储、遍历与应用 源代码

实验四图的存储、遍历与应用姓名:班级: 学号:日期:一、实验目的: 二、实验内容: 三、基本思想,原理和算法描述:

四、源程序: (1)邻接矩阵的存储: #include #include #define INFINITY 10000 //定义最大值无穷大 #define MAX_VERTEX_NUM 20 //最大顶点个数 typedef int AdjMatrix[MAX_VERTEX_NUM ][MAX_VERTEX_NUM ]; typedef struct{ int vexs[MAX_VERTEX_NUM ]; //顶点向量 AdjMatrix arcs; //邻接矩阵 int vexnum,arcnum; //图的当前顶点数和弧或边数 }MGraph; void CreatGragh(MGraph G) //用邻接矩阵构造图 { int i,j,k,w; printf("请输入顶点个数和边数:\n"); scanf("%d %d",&G.vexnum,&G.arcnum); printf("请按顺序输入顶点中间用‘空格’间隔\n"); for(i=0;i #include

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

南昌航空大学实验报告 课程名称:数据结构实验名称:实验八图地遍历 班级:学生姓名:学号: 指导教师评定:签名: 题目:假设无向图采用邻接表结构表示.编程分别实现图地深度优先搜索算法和广度优先搜索算法. 一、需求分析 1.用户可以根据自己地需求分别输入任意地一个有向图(可以是非连通图也可以是连通 图). 2.通过用广度优先遍历和深度优先遍历已有地图,并输出. 3.并且以邻接表地形式输出该已有地图. 4.程序执行地命令包括: (1)输入图地结点和弧构造图(2)输出图(2)广度优先遍历图(3)深度优先遍历图 二、概要设计 ⒈为实现上述算法,需要链表地抽象数据类型: ADT Graph { 数据对象V:V是具有相同特征地数据元素地集合,称为顶点集. 数据关系R: R={VR} VR={|v,w∈V且P(v,w),表示从x到w地弧,谓词P(v,w)定义了弧 地意义或信息 }b5E2R。 基本操作P: Creatgraph(&G,V,VR) 初始条件:V是图地顶点集,VR是图中弧地集合. 操作结果:按V和VR地定义构造图G. destroygraph(&G) 初始条件:图G存在. 操作结果:销毁图G. displaygraph(G) 初始条件:图G存在. 操作结果:显示图G. locatevex(G,u) 初始条件:图G存在,u和G中地顶点有相同地特征. 操作结果:若G中存在顶点u,则返回该顶点在图中位置,否则返回 其他信息.

getvex(G,v) 初始条件:图G存在,v是G中地某个顶点. 操作结果:返回v地值. DFStraverse (G) 初始条件:图G存在. 操作结果:对图进行深度优先遍历.在遍历过程中对每个顶点访问一 次. BFStraverse (&S,e) 初始条件:图G存在. 操作结果:对图进行广度优先遍历.在遍历过程中对每个顶点访问一 次. }ADT Graph 2. 本程序有三个模块: ⑴主程序模块 main(){ 初始化; { 接受命令; 显示结果; } } ⑵创建图地模块:主要建立一个图; ⑶广度优先遍历和深度优先遍历模块:输出这两种遍历地结果; (4)输出图模块:显示已创建地图. 三、详细设计 ⒈元素类型,结点类型 struct arcnode { int adjvex; /*该弧所指向地顶点地位置*/ int info; struct arcnode *nextarc; /*指向下一条弧地指针*/ }; struct vexnode { int data; /*顶点地信息*/ struct arcnode *firstarc; /*指向第一条依附该顶点地弧地指针*/ }; struct graph { struct vexnode *vexpex; int vexnum,arcnum; /*图地当前地顶点数和弧数*/ }; /*定义队列*/ struct queue { int *elem;

数据结构实验 - 图的储存与遍历

一、实验目的 掌握图这种复杂的非线性结构的邻接矩阵和邻接表的存储表示,以及在此两种常用存储方式下深度优先遍历(DFS)和广度优先遍历(BFS)操作的实现。 二、实验内容与实验步骤 题目1:对以邻接矩阵为存储结构的图进行DFS 和BFS 遍历 问题描述:以邻接矩阵为图的存储结构,实现图的DFS 和BFS 遍历。 基本要求:建立一个图的邻接矩阵表示,输出顶点的一种DFS 和BFS 序列。 测试数据:如图所示 题目2:对以邻接表为存储结构的图进行DFS 和BFS 遍历 问题描述:以邻接表为图的存储结构,实现图的DFS 和BFS 遍历。 基本要求:建立一个图的邻接表存贮,输出顶点的一种DFS 和BFS 序列。 测试数据:如图所示 三、附录: 在此贴上调试好的程序。 #include #include #include ????????????????=010******* 010101000100010A

#define M 100 typedef struct node { char vex[M][2]; int edge[M ][ M ]; int n,e; }Graph; int visited[M]; Graph *Create_Graph() { Graph *GA; int i,j,k,w; GA=(Graph*)malloc(sizeof(Graph)); printf ("请输入矩阵的顶点数和边数(用逗号隔开):\n"); scanf("%d,%d",&GA->n,&GA->e); printf ("请输入矩阵顶点信息:\n"); for(i = 0;in;i++) scanf("%s",&(GA->vex[i][0]),&(GA->vex[i][1])); for (i = 0;in;i++) for (j = 0;jn;j++) GA->edge[i][j] = 0; for (k = 0;ke;k++) { printf ("请输入第%d条边的顶点位置(i,j)和权值(用逗号隔开):",k+1); scanf ("%d,%d,%d",&i,&j,&w); GA->edge[i][j] = w; } return(GA); } void dfs(Graph *GA, int v) { int i; printf("%c%c\n",GA->vex[v][0],GA->vex[v][1]); visited[v]=1;

图地深度广度遍历(算法与大数据结构课程设计)

图的操作 一、问题描述 图是一种较线性表和树更为复杂的数据结构。在图形结构中,节点间的关系可以是任意的,图中任意两个数据元素之间都可以相关。由此,图的应用极为广泛。现在邻接矩阵和邻接表的存储结构下,完成图的深度、广度遍历。 二、基本要求 1、选择合适的存储结构完成图的建立; 2、建立图的邻接矩阵,能按矩阵方式输出图,并在此基础上,完成图的深度和广度遍历,输出遍历序列; 3、建立图的邻接表,并在此基础上,完成图的深度和广度遍历,输出遍历序列; 三、测试数据 四、算法思想 1、邻接矩阵 顶点向量的存储。用两个数组分别存储数据(定点)的信息和数据元素之间的关系(边或弧)的信息。 2、邻接表 邻接表是图的一种链式存储结构。在邻接表中,对图中每个定点建立一个单链表,第i 个单链表中的节点表示依附于定点vi的边。每个节点由3个域组成,其中邻接点域(adjvex)指示与定点vi邻接的点在图中的位置,链域(nextarc)指示下一条边或弧的节点;数据域(info)存储和边或弧相关的信息,如权值等。每个链表上附设一个头节点。在表头节点中,

除了设有链域(firstarc)指向链表中第一个节点之外,还设有存储定点vi的名或其他有关信息的数据域(data)。 3、图的深度遍历 深度优先搜索遍历类似于树的先根遍历,是树的先跟遍历的推广。假设初始状态是图中所有顶点未曾被访问,则深度优先搜索可从图中某个顶点v出发,访问此顶点,然后依次从v的未被访问的邻接点出发深度优先遍历图,甚至图中所有和v相通的顶点都被访问到;若此时图有顶点未被访问,则另选图中一个未曾被访问的顶点作起始点,重复上述过程,直至图中所有顶点都被访问到为止。 4、图的广度遍历 广度优先遍历类似于树的按层次遍历过程。假设从图中某顶点v出发,在访问了v之后依次访问v的各个未曾访问过的邻接点,然后分别从这些邻接点出发依次访问它们的邻接点,并使“先被访问的顶点的邻接点”先与“后被访问的顶点的邻接点”被访问,直至图中所有已被访问的顶点的邻接点都被访问到。若此时图有顶点未被访问,则另选图中一个曾被 访问的顶点作起始点,重复上述过程,直至图中所有顶点都被访问到为止。 五、模块划分 一、基于邻接矩阵的深广度遍历 1.Status InitQueue(LinkQueue *Q) 根据已知Q初始化队列 2.Status QueueEmpty (LinkQueue Q) 判断队列是否为空 3.Status EnQueue(LinkQueue *Q, QElemType e) 将e压入队尾 4.Status DeQueue(LinkQueue *Q, QElemType *e) 取队头元素e 5.int LocateVex(MGraph G,VertexType v) 定位定点v 6.void CreateGraph(MGraph *G) 建立无向图的邻接矩阵 7.void PrintGraph(MGraph G) 输出邻接矩阵的无向图 8.int FirstAdjVex(MGraph G,int v) 第一个邻接点的定位 9.int NextAdjVex(MGraph G,int v,int w) 查找下一个邻接点

数据结构实验七图的创建与遍历

实验七图的创建与遍历 实验目的: 通过上机实验进一步掌握图的存储结构及基本操作的实现。 实验内容与要求: 要求: ⑴能根据输入的顶点、边/弧的信息建立图; ⑵实现图中顶点、边/弧的插入、删除; ⑶实现对该图的深度优先遍历; ⑷实现对该图的广度优先遍历。 备注:单号基于邻接矩阵,双号基于邻接表存储结构实现上述操作。算法设计: #include #include #define INFINITY 32767 #define MAX_VEX 20 //最大顶点个数#define QUEUE_SIZE (MAX_VEX+1) //队列长度 using namespace std; bool *visited; //访问标志数组 //图的邻接矩阵存储结构 typedef struct{ char *vexs; //顶点向量 int arcs[MAX_VEX][MAX_VEX]; //邻接矩阵 int vexnum,arcnum; //图的当前顶点数和弧数 }Graph; //队列类 class Queue{ public: void InitQueue() { base=(int *)malloc(QUEUE_SIZE*sizeof(int)); front=rear=0; } void EnQueue(int e) { base[rear]=e; rear=(rear+1)%QUEUE_SIZE; } void DeQueue(int &e) { e=base[front]; front=(front+1)%QUEUE_SIZE; } public: int *base; int front; int rear; }; //图G中查找元素c的位置 int Locate(Graph G,char c) { for(int i=0;i

数据结构 图的遍历(初始化图)

实践四:图及图的应用 1.实验目的要求 理解图的基本概念,两种主要的存储结构。掌握在邻接链表存储结构下的图的深度优先递归遍历、广度优先遍历。通过选做题"最短路径问题"认识图及其算法具有广泛的应用意义。 实验要求:正确调试程序。写出实验报告。 2.实验主要内容 2.1 在邻接矩阵存储结构下的图的深度优先递归遍历、广度优先遍历。 2.1.1 要完成图的两种遍历算法,首先需要进行图的数据初始化。为把时间主要花在遍历算法的实现上,图的初始化采用结构体声明时初始化的方法。示例代码如下: #include "stdio.h" typedef int Arcell; typedef int AdjMatrix[5][5]; typedef struct { char vexs[5]; AdjMatrix arcs; int vexnum,arcnum; }MGraph; void main(){ MGraph g={ {'a','b','c','d','e'}, {{0,1,0,1,0}, {1,0,0,0,1}, {1,0,0,1,0}, {0,1,0,0,1}, {1,0,0,0,0}} ,5,9}; } 2.1.2 深度优先遍历算法7.5中FirstAdjVex方法和NextAdjVex方法需要自己实现。 2.2 拓扑排序,求图的拓扑序列 2.3 "最短路径问题",以校园导游图为实际背景进行设计。(选做) 程序代码如下: #include

#include #define TRUE 1 #define FALSE 0 #define MAX 20 #define NULL 0 #define OK 1 #define OVERFLOW -2 #define ERROR 0 typedef int Status; typedef int Boolean; typedef int QElemType; // 图的邻接矩阵存储结构typedef struct ArcCell{ int adj; }ArcCell, AdjMatrix[20][20]; typedef struct { char vexs[20]; AdjMatrix arcs; int vexnum,arcnum; }Graph; //队列的链式存储结构typedef struct QNode{ QElemType data; struct QNode * next; }QNode, *QueuePtr;

数据结构_图遍历的演示

实习报告 题目:图遍历的演示 编译环 境: Microsoft Visual Studio 2010 功能实现: 以邻接表为存储结构,演示在连通无向图上访冋全部节点的操作; 实现连通无向图的深度优先遍历和广度优先遍历; 建立深度优先生成树和广度优先生成树,按凹入表或树形打印生成树。 1.以邻接表为存储结构,演示在连通无向图上访问全部节点的操作。 该无向图为 一个交通网络,共25个节点,30条边,遍历时需要以用户指定的节点为起点, 建立深度优先生成树和广度优先生成树,再按凹入表或树形打印生成树。 2.程序的测试数据:graph.txt 文件所表示的无向交通图。 //边表结点 //邻接点域,即邻接点在顶点表中的下标 //顶点表结点 //数据域 struct TNode // 树结点 { stri ng data; struct TNode *fristchild, * nextchild; }; 2.邻接表类设计: class GraphTraverse { public: 需求分析 二、概要设计 1.主要数据结构设计: struct ArcNode { int vex In dex; ArcNode* n ext; }; struct VertexNode { stri ng vertex; ArcNode* firstArc; };

三、详细设计 1. 主要操作函数的实现: (1) 建立深度优先生成树函数: TNode* GraphTraverse::DFSForest(i nt v) { int i,j; TNode *p,*q,*DT; j=v; for(i=O;idata=VexList[(i+j)%vertexNumberber].vertex; p->fristchild=NULL; p-> nextchild=NULL; DT=p; q=p; DFSTree(((i+j)%vertexNumberber),p); } } return DT; } (2) 深度优先遍历图函数: VertexNode VexList[MaxSize]; int vertexNumberber; int arcNumberber; bool HasCreated; void ReadFile(); void DisplayGraph(); TNode* DFSForest(i nt); void DFSTree(i nt, TNode*); TNode* BFSForest(i nt); void BFSTree(i nt, TNode*); void Prin tTree(TNode*, i nt); }; //顶点表数组 //图的顶点数 //图的边数 //图是否创建 //从文件读取数据,并建立该图 //以邻接表显示图 //建立深度优先生成树 //深度优先遍历图 //建立广度优先生成树 //广度优先遍历图 //按照凹入表方式打印树

相关文档
最新文档