实验六 图的创建及应用(I)
实验六 框架窗口、文档和视图

实验六框架窗口、文档和视图一实验内容创建一个基于ClistView视图的单文档应用程序Ex_Student,通过对话框输入一个学生记录,记录包括学生的姓名、学号和3门成绩。
然后将记录内容保存到一个对象数组集合类对象中,最后通过文档序列化将记录保存到一个文件中。
当添加记录或打开一个记录文件时,还会将数据显示在文档窗口中。
二实验步骤1.创建工作文件夹2.参照文档序列化实例添加用于学生记录输入的对话框,对话框布局如图所示;4.添加一个Cstudent类使该类可序列化在Ex_StudentDoc.h文件中的class CEx_StudentDoc前添加class CStudent:public CObject{CString strName;CString strID;float fScore1,fScore2,fScore3;float fAverage;DECLARE_SERIAL(CStudent)public:CStudent(){};CStudent(CString name,CString id,float f1,float f2,float f3);void Serialize(CArchive &ar);void Display(int y,CDC*pDC);//在坐标为(0,y)处显示数据};在Ex_StudentDoc.cpp文件中添加Cstudent实现代码CStudent::CStudent(CString name,CString id,float f1,float f2,float f3){strName=name;strID=id;fScore1=f1;fScore2=f2;fScore3=f3;fAverage=(float)((f1+f2+f3)/3.0);}void CStudent::Display(int y,CDC*pDC){CString str;str.Format("%s %s %f %f %f %f",strName,strID,fScore1,fScor2,fScore3,fAverage);pDC->TextOut(0,y,str);}IMPLEMENT_SERIAL(CStudent,CObject,1)void CStudent::Serialize(CArchive &ar){if(ar.IsStoring())ar<<strName<<strID<<fScore1<<fScore2<<fScore3<<fAverage;elsear>>strName>>strID>>fScore1>>fScore2>>fScore3>>fAverage;}5.添加并处理菜单项为CEx_StudentDoc类添加ID_STUREC_ADD的COMMAND消息映射,并在映射函数中添加下列代码:CAddDlg dlg;if(IDOK==dlg.DoModal()){//添加记录CStudent *pStudent=new CStudent(dlg.m_strName,dlg.m_strID,dlg.m_fScore1,dlg.m_fScore2,dlg.m_fScore3);m_stuObArray.Add(pStudent);SetModifiedFlag();//设置文档更改标志UpdateAllViews(NULL);//更新视图}6.在Ex_StudentDoc.cpp文件的开始处增加包含CAddDlg的头文件#include "AddDlg.h"7.完善代码(1)在Ex_StudentDoc.h文件中,添加下列成员变量和成员函数public:CObArray m_stuObArray;int GetAllRecNum(void);CStudent* GetStudentAt(int nIndex);(2)在Ex_StudentDoc.cpp文件中添加函数的实现代码:CStudent*CEx_StudentDoc::GetStudentAt(int nIndex){if((nIndex<0)||nIndex>m_stuObArray.GetUpperBound())return 0;return(CStudent*)m_stuObArray.GetAt(nIndex);}int CEx_StudentDoc::GetAllRecNum(){return m_stuObArray.GetSize();}(3)在CEx_StudentDoc析构函数中添加下列代码:int nIndex=GetAllRecNum();while(nIndex--)delete m_stuObArray.GetAt(nIndex);m_stuObArray.RemoveAll();(4)在Serialize函数中添加下列代码:void CEx_StudentDoc::Serialize(CArchive& ar){if (ar.IsStoring()){m_stuObArray.Serialize(ar);}else{m_stuObArray.Serialize(ar);}}(5)在OnDraw函数中添加代码:int y=0;for(int nIndex=0;nIndex<pDoc->GetAllRecNum();nIndex++) {pDoc->GetStudentAt(nIndex)->Display(y,pDC);y+=16;}(6)打开文档字串资源将其内容修改为编译运行后点击学生记录中的添加记录显示如下:而且生成一个文件8.在上述基础上修改代码(1)修改类Cstudent的声明:将void Display(int y,CDC*pDC);改为void Display(int nIndex,CListCtrl *pList); (2)修改Display成员函数的实现代码为:void CStudent::Display(int nIndex,CListCtrl *pList){ int nSub=pList->InsertItem(nIndex,strName);CString str;pList->SetItemText(nSub,1,strID);str.Format("%5.1f",fScore1);pList->SetItemText(nSub,2,strID);str.Format("%5.1f",fScore2);pList->SetItemText(nSub,3,strID);str.Format("%5.1f",fScore3);pList->SetItemText(nSub,4,str);}(3)修改OnStureAdd函数中的代码:将UpdateAllViews(NULL);//更新视图改为UpdateAllViews(NULL,1);//更新视图(4)在View类中添加一个成员函数DispAllRec,用于将文档中的记录数据全部显示在列表控件中,其代码如下:void CEx_StudentView::DispAllRec(){CEx_StudentDoc* pDoc=GetDocument();ASSERT_V ALID(pDoc);CListCtrl&m_ListCtrl=GetListCtrl();m_ListCtrl.DeleteAllItems();int y=0;for(int nIndex=0;nIndex<pDoc->GetAllRecNum();nIndex++){pDoc->GetStudentAt(nIndex)->Display(y,&m_ListCtrl);y++;}}(5)在CEx_StudentView::PreCreateWindow函数中添加下列代码:cs.style|=LVS_REPORT;(6)在OnInitialUpdate函数中添加设置列表控件表头的代码://删除列表头int nColumnCount=m_ListCtrl.GetHeaderCtrl()->GetItemCount();for(int i=0;i<nColumnCountli++)m_ListCtrl.DeleteColumn(0);//添加列表头CListCtrl& m_ListCtrl=GetListCtrl();char* arCols[5]={"姓名","学号","成绩1","成绩2","成绩3");for(int nCol=0;nCol<5;nCol++)m_ListCtrl.InsertColumn(nCol,arCols[nCol],LVCFMT_LEFT,100);m_ListCtrl.SetExtendedStyle(LVS_EX_FULLROWSELECT|LVS_EX_GRIDLINES);DispAllRec();(7)为View类添加OnUpdate消息函数,并添加下列代码;void CEx_StudentView::OnUpdate(CView* pSender, LPARAM lHint, CObject* pHint){if(lHint==1) DispAllRec();}(8)删除刚才在Draw中添加的代码三.实验结果能通过对话框添加一个学生记录,还能显示在表格里面,最后记录内容保存到一个文件中四.实验心得本次试验中用到CListCtrl&m_ListCtrl=GetListCtrl();如果开始创建的单文档应用程序不是基于ClistView,此处就会报错,说GetListCtrl();没有定义,因为此函数是继承ClistView这个基类的。
计算机网络实验(六大实验)详解

第四步:验证配置
switch#show vlan
VLAN Name Type Media Ports ---- ------------ ---------- --------- ---------------------------------------1 default Static ENET Ethernet0/0/17 Ethernet0/0/18 Ethernet0/0/19 Ethernet0/0/20 Ethernet0/0/21 Ethernet0/0/22 Ethernet0/0/23 Ethernet0/0/24 100 VLAN0100 Static ENET Ethernet0/0/1 Ethernet0/0/2 Ethernet0/0/3 Ethernet0/0/4 Ethernet0/0/5 Ethernet0/0/6 Ethernet0/0/7 Ethernet0/0/8 200 VLAN0200 Static ENET Ethernet0/0/9 Ethernet0/0/10 Ethernet0/0/11 Ethernet0/0/12 Ethernet0/0/13 Ethernet0/0/14 Ethernet0/0/15 Ethernet0/0/16
启动 telnet服务
关于跨网段的问题
在PC机上可以使用telnet方式远程管理不同 网段的交换机。 一般来说对于同网段的交换机管理时对交换 机配置和PC机设置一个管理性IP地址和一 个同网段的IP就可以了,当要从一个交换机 跨网段管理另一个交换机时需要给交换机网 关设置。
在交换机所在网段内的工作站pc-01可以 使用telnet方式远程管理该交换机。 如果现在用户登录到switch-01中,想利 用网络远程管理另一个网段的交换机 switch-02就需要在双方交换机设置一个 默认网关,表示交换机无法转发的数据帧 就交给该IP地址(网关IP地址)的设备处 理以便能完成数据帧的转发过程;发送的 过程如下图:
实验六+图形界面

实验六图形界面实验日期: 2016 年 6 月 12 日班级:软件1401 学号(后四位):__0127_______ 姓名:_程瑞强_______ 成绩:成绩:一.实验目的1.掌握图形用户界面的设计方法2.掌握常用的构建用户界面的组件的用法3.掌握事件操作的原理4.能够对所设计的用户界面进行事件处理5.能够应用运算符解决实际小问题6.进一步熟悉Java的面向对象的编程思想二.实验题目(前2题任选1题,第3,4题任选1题)1.采用图形界面实现两个内容的交换,图形界面如下图1所示所示:图1 内容交换代码如下:package TestChange;import class TestChange extends JFrame implements ActionListener{private static final long serialVersionUID = -006L;JPanel panel;JTextField tt1;JTextField tt2;JButton button;public TestChange(){("TestChange");(355, 85);;panel = new JPanel();tt1 = new JTextField(10);tt2 = new JTextField(10);button = new JButton("Change");(this);(tt1);(tt2);(button);(panel, ;(false);(true);}public static void main(String[] str){ new TestChange();}@Overridepublic void actionPerformed(ActionEvent e) {if() == button){String temp = ();());(temp);}}}2. 采用图形界面设计如下图2所示的界面。
实验六 视图的创建和使用

实验六视图的创建和使用开课实验室:指导老师:学院:专业(班级):姓名:学号:一、实验目的与要求1)理解视图的概念2)掌握利用企业管理器和CREATE VIEW命令创建视图方法。
3)熟悉修改视图、查看视图和删除视图的方法。
4)掌握通过视图修改数据表的方法二、实验过程设计及实验步骤创建视图是数据库应用中的常见需求,可以使用企业管理器创建、管理视图,也可以用T-SQL语句创建、管理视图。
1)在企业管理器中创建如下视图:在XSGL数据库中使用表STUDENT和SCORE 创建视图VIEW_STUDENTSCROE,来查询每个学生的姓名和选课情况。
2)在查询分析器中创建视图:将上题用CREATE VIEW 来创建,视图名为VIEW2 程序代码:3)查看视图信息:使用系统存储过程SP_HELP、SP_HELPTEXT、SP_DEPENDS4)删除视图:将视图VIEW2删除.三、SQL调试及结果创建视图是数据库应用中的常见需求,可以使用企业管理器创建、管理视图,也可以用T-SQL语句创建、管理视图。
1)在企业管理器中创建如下视图:在XSGL数据库中使用表STUDENT和SCORE 创建视图VIEW_STUDENTSCROE,来查询每个学生的姓名和选课情况。
2)在查询分析器中创建视图:将上题用CREATE VIEW 来创建,视图名为VIEW2 程序代码:CREATE VIEW VIEW2ASSELECT STUDENT.SNAME,OFROM STUDENT,SCORE3)查看视图信息:使用系统存储过程SP_HELP、SP_HELPTEXT、SP_DEPENDS 执行代码;SP_HELPTEXT VIEW2执行代码:SP_HELP VIEW2执行代码:SP_DEPENDS VIEW24)删除视图:将视图VIEW2删除. 执行语句:USE XSGLDROP VIEW VIEW2四、实验体会通过此次学习我理解视图的概念,掌握利用企业管理器和CREATE VIEW命令创建视图方法。
CAD课程实验结果报告

实验一电原理图的编辑(1)一、实验目的:1、了解Protel 99 SE的启动、绘图环境、各个功能模块、界面环境设置方法和文件管理方法。
2、掌握电路原理图的设计步骤、Portel 99 SE电路原理图设计环境,图纸设置的内容和方法。
3、掌握装载元器件库,放置、编辑和调整元器件,设置网格、电气节点和光标形状的方法,并能绘制简单的电原理图。
二、实验设备:装有protel 99 se 软件的PC机一台。
三、实验要求:1.试验前,仔细阅读教材相关内容,设计能够完成试验内容的试验步骤,写好试验预习报告。
2.试验后,完成试验报告,其中的试验步骤应是经过试验证明为正确的步骤。
四、试验内容:1.查看Protel 99 SE的运行环境,包括所用机器的硬件与软件环境。
2.学习使用Protel 99 SE的基本操作,包括进入Protel 99 SE主程序、菜单操作,工具栏操作及退出等基本操作。
3.打开安装目录\Examples\Z80 Microprocessor.ddb设计数据库,通过打开其中的各种设计文件熟悉Protel 99 SE的绘图环境,各个功能模块,界面环境,并练习Protel 99 SE的文件管理功能。
4.在自己的用户目录下,创建一个自己的设计数据库,新建一个原理图文件并打开。
(设计数据库、原理图文件的主文件名自定)5.设置自己喜爱的绘图环境,如图纸类型、尺寸、底色、光标形状、可视栅格、栅格形状、大小等等。
6.在新建的原理图文件中绘制教材图2-10所示的原理图。
五、实验步骤:1、启动Protel99SE,单击“设计文件管理”窗口内的“Documents”文件夹或双击工作窗口的”Documents”标签后执行“File”菜单下的“NEW”命令,选择相应的文件类型,Schematic Documents,单击ok按钮将生成相应的设计文件。
2、设置SCH编辑器的工作参数。
3、选择图纸封面、标题栏格式样、图纸放置方向。
实验六 图及其应用

实验六图及其应用数据结构实验六图及其应用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 已经存在;操作结果:返回图从某个结点开始的按广度遍历的结果。
分析: 修改输入数据,预期输出并验证输出的结果,加深对有关算法的理解。
实验六 Word表格制作与图片处理
实验六 Word表格制作和图片处理一、实验目的1.掌握表格的创建、编辑和格式化。
2.掌握单元格的计算、表格排序、表格生成图表。
3.掌握插入图片、编辑图片、图片格式化、绘制图形。
4.掌握艺术字体的使用。
5.掌握公式编辑器的使用。
6.掌握文本框的使用。
7.掌握图、文混排、页面排版。
二、预备知识1.创建表格(1)快速创建简单表格。
方法1:单击“常用”工具栏的“插入表格”按钮,按住鼠标左键并拖曳到所需表格的行、列格数,如图6.1所示,即可创建一个规则表格。
方法2:单击菜单栏的“表格”→“插入”→“表格”命令,弹出“插入表格”对话框,如图6.2所示。
选择所需的行数和列数,单击“确定”按钮。
图6.1快速创建表格图6.2“插入表格”对话框(2)创建复杂表格。
方法1:单击菜单栏的“表格”→“绘制表格”命令。
方法2:单击“常用”工具栏的“表格和边框”按钮。
都将弹出“表格和边框”工具栏,如图6.3所示。
此时,自动选中“绘制表格”按钮,光标呈一铅笔状,可用于在表格中画水平、垂直及斜线;单击“擦除”按钮,光标呈橡皮擦状,沿表格线拖曳或单击可删除该表格线;表格绘制完成后再单击“绘制表格”按钮,取消选定状态。
也可使用表格的“拆分与合并”功能完成不规则表格的绘制。
图6.3“表格和边框”工具栏(3)绘制带斜线的表头。
①将光标定位于表头(表的第1行第1列)。
②单击菜单栏的“表格”→“绘制斜线表头”命令,弹出“插入斜线表头”对话框,如图6.4所示。
③选择表头样式,并在相应文本框中输入标题内容,单击“确定”按钮。
(4)在表格中输入文字。
表格中的每一个单元格都可以看做独立的文档来录入文本,回车将在单元格中另起一行。
若要设置文字的对齐方式,选取单元格,单击鼠标右键,选择快捷菜单中的“单元格对齐方式”命令,弹出“对齐方式”按钮供选择,如图6.5所示。
单击所需要的“对齐方式”按钮即可。
图6.4“插入斜线表头”对话框图6.5“单元格对齐方式”按钮2. 编辑表格(1)在表格中添加行或列。
实验六 状态机图
实验六状态机图一、实验目的1.熟悉状态图的基本功能和使用方法。
2.初步掌握创建状态图的方法。
3.掌握如何使用建模工具Rational Rose2003绘制状态图方法。
二、实验器材1.计算机一台。
2.Rational Rose 2003工具软件。
三、实验内容通过前面内容的学习,完成了对图书管理系统需求的初步分析,得出系统的用例图和相应的活动图。
通过这两类图我们可以初步了解系统的业务处理过程,但对业务处理过程的处理状态间转换了解仍不够,而状态图能从对象的动态行为的角度去描述系统的业务活动。
具体包括:1.确定状态图的实体。
2.确定实体的状态。
3.确定相关事件。
4.使用Rational Rose工具绘制状态图。
四、实验步骤(具体方案)(一)在整个的系统中书籍和借阅者对象的状态变换最为复杂,因此对书籍和借阅者对象建立状态图。
1.图书状态图:图书包含以下的状态:刚被购买后的新书、被添加能够借阅时的图书、图书被预定、图书被借阅、图书被管理员删除。
它们之间的转化规则是:(1)刚被购买后的新书可以通过系统管理员添加成为能够被借阅的图书。
(2)图书被预定成为被预定状态。
(3)当被预定的图书超过预定期限或者被借阅者取消预定时,转换为能够被借阅的图书状态。
(4)被预定的图书可以被预定的借阅者借阅。
(5)图书被借阅后成为被借阅状态。
(6)图书被借阅后归还成为能够借阅状态。
(7)图书被删除时成为被删除状态。
状态图如下:图6.12.借阅者状态图借阅者包含以下的状态:借阅者帐户创建、借阅者能够借阅图书、借阅者不能够借阅图书、借阅者被管理员删除。
它们之间的转化规则是:(1)借阅者通过创建借阅者帐户成为能够借阅图书的借阅者。
(2)当借阅者借阅图书数目超过一定限额,不能够借阅图书。
(3)当借阅者处于不能够借阅图书时,借阅者归还借阅图书,成为能够借阅状态。
(4)借阅者能够借阅一定数目的图书。
(5)借阅者能够被系统管理员删除。
状态图如下:。
实验六 视图和索引 实验指导
实验六视图和索引实验指导一、视图视图是SQL Server中重要的数据库对象。
视图常用于集中、简化和定制显示数据库的数据信息,为用户从多种角度观察数据库中的数据提方便。
为了屏蔽数据的复杂性、简化用户对数据的操作、控制用户访问数据的权限、保护数据安全,常为不同的用户创建不同的视图。
1. 视图的基本概念视图是从一个或多个表或视图导出的表;其结构和数据是建立在对表的查询基础上的。
和表一样,视图也是包括几个被定义的数据列和多个数据行。
但就本质而言,这些数据列和数据行来源于其所引用的表。
所以,视图不是真实存在的基础表,而是一张虚表。
视图所对应的数据并不实际地以视图结构存储在数据库中,而是存储在视图所引用的表中。
视图一经定义便存储在数据库中,与其相对应的数据并没有像表那样又在数据库中再存储一份。
通过视图看到的数据,只是存放在基本表中的数据。
对视图的操作与对表的操作一样,可以对其进行查询、修改(有一定的限制)、删除。
当对通过视图看到的数据进行修改时,相应的基本表的数据也要发生变化,同时若基本表的数据发生变化,则这种变化也可以自动地反映到视图中。
可以将任何符合视图创建规定的SELCT语句命名和存储为视图。
在视图中北查询的表称为基表。
视图的常见实例如下。
●一个基表的行或列的于集。
●两个或多个表的合并。
●两个或多个表的联接。
●一个基表的统计总汇。
●另外一个视图的子集。
●视图和基表的混合。
2. 创建视图在SQL Server2008中创建视图,创建者必须拥有创建视图的权限,并且对视图中引用的基表或视图有许可权。
此外,创建视图前还应该注意以下几点:●只能在当前数据库中创建视图。
如果使用分布式查询,视图所引用的基表和视图可以存在于其他数据库或其他服务器中。
●在一个视图中最多引用1024列,视图中记录的行数限制由基表中的记录数目决定。
●视图的名称必须遵循标识符的命名规则,且对每个架构都必须唯一,并且该名称不得与该架构包含的任何表的名称相同。
UML实验报告
1.为什么要求相对应的类名、组件名和实现组件的文件名相同?
答:相应的名字中能够找到相应的类的信息。如果组件名、类名和Java文件名不相同,会出现实体类的语法错误。
实验七 正向工程
一、实验报告要求
1.整理实验结果。
2.小结实验心得体会。
正向工程是对一个系统物理结构实现的高层抽象性、逻辑性及独立性设计的传统处理过程。通过本次试验,学会了利用Rose工具生成代码框架及生成数据库脚本,同时在实现过程中使用转换后的代码和数据库脚本。了解了Java编程综合练习。
实验四 活动图
一、实验结果
1.整理实验结果。
2.小结实验心得体会
在UML中,活动图是为系统的动态方面建模的7个图之一。活动图主要是一个流图,它描述了从活动到活动的控制流,它还可以用来描述对象在控制流的不同点从一个状态转移到另一个状态时的对象流。
通过本次实验,我对活动图的语义和功能有了更深层次的理解和应用,并对活动图的组成部分,包括动作状态、活动状态、分支、分叉和泳道、对象流,逐一进行了学习。同时基本掌握了用活动图来描述系统中“借出图书”用例的业务过程。实验过后本应该有完整的截图,由于自己的粗心马虎,造成截图的不完整性。
2.本案例中,ResourceTitle与BookTitle、DiscTitle的继承关系,SQL Server 2000关系型数据库的转换合理吗?如不合理,请问该如何修改?
答:不合理。
UML
实
验
报
告
实验一 用例图
一、实验结果
1、整理实验结果
2、小结实验心得体会
用例模型用于需求分析阶段,它描述了待开发系统的功能需求,并驱动了需求分析之后各阶段的开发工作。用例图是UML中用来对系统的动态方面进行建模的7种图之一。用例图描述了用例、参与者以及它们之间的关系。用例图从用户角度描述系统功能,并指出各功能的操作者。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
姓名学号算本次实验主函数采用循环选择结构,主函数调用自己编写的头文件DataStructure_Graph.h中的相关功能函数,完成实验要求。
主程序结构:1、邻接矩阵表示法:1、创建有向图;//调用CreateGraph(MG)创建有向图2、显示图信息;//调用DisplayGraph(MG) 显示图信息3、返回上一界面;2、邻接表表示法:1、创建有向图; //调用CreateGraph(ALG)创建有向图2、显示图信息;//调用DisplayGraph(ALG) 显示图信息3、返回上一界面;3、基于深度优先搜索判断是否存在指定位置的路径:1、使用已创建的邻接表表示的图进行搜索判断;//调用exist_path_DFS(ALG, i, j)搜索2、创建新的图进行搜索判断;//创建新的有向图,并调用exist_path_DFS(R_ALG, i, j)搜索3、返回上一界面;4、退出程序创建图的算法分析邻接矩阵结构创建图:首先由键盘输入待创建的图的顶点数,弧数以及是否含有弧信息,然后由顶点数控制循环构造顶点向量,接着由顶点数控制循环初始化邻接矩阵(adj=0,info=NUll),再次输入弧信息,此时将输入的弧的弧头和弧尾与顶点信息进行匹配,从而确定弧在邻接矩阵中的位置(有弧时为1),如果输入的弧有信息的话,在进行有无弧的判断写邻接矩阵时进行绑定,有键盘输入即可。
邻接表结构创建图:首先由键盘输入待创建的图的顶点数,弧数,然后由顶点数控制循环初始化顶点信息(顶点数据信息及顶点第一条弧指针(firstarc = NULL)),接着由弧数控制循环输入弧头和弧尾顶点,与之前建立的顶点信息进行匹配,从而确定弧头和弧尾的位置信息,此时生成一个弧结点类型的存储空间,采用单链表中在表头插入新结点的方法,将弧的信息插入到顶点的第一条弧之后,如同此法,对每个顶点都进行以上操作,这就建立了图的邻接表结构。
深度优先搜索判断是否存在指定位置的路径算法分析首先判断指定的两个位置向量是否相等,如果相等,则肯定有路径相连,否则从指定的弧头结点开始搜索,将该顶点访问过的弧的访问标志置1,任何到该弧的弧头顶点进行如上操作,当搜索该顶点的所有弧都没有找到则返回0,然后返回上一顶点,对该顶点的其他弧进行访问。
当指定顶点的所有弧都被搜索访问过都没有找到,此时程序返回0。
cout << endl << ">请选择功能:";cin >> ch1;switch (ch1){case'1': //创建有向图{system("cls");CreateGraph(MG);cout << "操作完毕!" << endl;system("pause");system("cls");continue;}case'2': //显示图信息{system("cls");DisplayGraph(MG);cout << "操作完毕!" << endl;system("pause");system("cls");continue;}case'3': //返回上一界面{break;}default:{system("cls");cout << "输入错误,请重新输入!" << endl;continue;}}system("cls");break;}break;}case'2':{system("cls");while (1){minor_menu2();char ch1;//二层菜单输入选择cout << endl << ">请选择功能:";cin >> ch1;switch (ch1){case'1'://创建图信息{system("cls");CreateGraph(ALG);cout << "操作完毕!" << endl;system("pause");system("cls");continue;}case'2'://显示图信息{system("cls");DisplayGraph(ALG);cout << "操作完毕!" << endl;system("pause");system("cls");continue;}case'3': //返回上一界面{break;}default:{system("cls");cout << "输入错误,请重新输入!" << endl;continue;}}system("cls");break;}break;}case'3':{system("cls");while (1){minor_menu3();ALGraph R_ALG;int i, j; //待搜索的顶点的位置char ch1; //二层菜单输入选择cout << endl << ">请选择功能:";cin >> ch1;switch (ch1){case'1'://使用已创建的邻接表表示的图进行搜索{system("cls");cout << "请输入待搜索的顶点v(i) 顶点v(j)(以空格分隔):";cin >> i>> j;int flag = exist_path_DFS(G, i, j);if (flag)cout << "搜索成功!存在顶点v(i):" << G.vertices[i].data << "顶点v(j):" << G.vertices[j].data << "的路径" << endl;elsecout << "搜索失败!不存在顶点v(i):" << G.vertices[i].data << "到顶点v(j):" << G.vertices[j].data << "的路径" << endl;cout << "操作完毕!" << endl;system("pause");system("cls");continue;}case'2': //创建新图进行搜索{system("cls");CreateGraph(R_ALG);cout << "请输入待搜索的顶点v(i) 顶点v(j)(以空格分隔):";cin >> i >> j;int flag = exist_path_DFS(R_ALG, i, j);if (flag)cout << "搜索成功!存在顶点v(i):" << R_ALG.vertices[i].data << "到顶点v(j):" << R_ALG.vertices[j].data << "的路径" << endl;elsecout << "搜索失败!不存在顶点v(i):" << R_ALG.vertices[i].data << "到顶点v(j):" << R_ALG.vertices[j].data << "的路径" << endl;cout << "操作完毕!" << endl;system("pause");system("cls");continue;}case'3': //返回上一界面{break;}default:{system("cls");cout << "输入错误,请重新输入!" << endl;continue;}}system("cls");break;}break;}case'4':{return 0;}default:{system("cls");cout << "功能选择错误,请重新输入!" << endl;break;}}}return 0;}void main_menu(void){cout << endl;cout << "==========================================================================" << endl;cout << " 图的创建及应用 " << endl;cout << "<<=========================功能选择========================>>" << endl;cout << " 【1】邻接矩阵表示法 " << endl;cout << " 【2】邻接表表示法 " << endl;cout << " 【3】基于深度优先搜索判断是否存在指定位置的路径 " << endl;cout << " 【4】退出程序 " << endl;cout << "==========================================================================" << endl <<endl;}void minor_menu1(void){cout << "<<=====邻接矩阵表示法=====>>" << endl;cout << ">1.创建有向图" << endl;cout << ">2.显示图信息" << endl;cout << ">3.返回上一界面" << endl;}void minor_menu2(void){cout << "<<=====邻接表表示法=====>>" << endl;cout << ">1.创建有向图" << endl;cout << ">2.显示图信息" << endl;cout << ">3.返回上一界面" << endl;}void minor_menu3(void){cout << "<<=====基于深度优先搜索判断是否存在指定路径=====>>" << endl;cout << ">1.使用已创建的邻接表表示的图进行搜索判断" << endl;cout << ">2.创建新的图进行搜索判断" << endl;cout << ">3.返回上一界面" << endl;}2.头文件”ADT.h”的部分程序如下:#ifndef ADT_H_#define ADT_H_/************************ 图 *************************//* ------图的数组(邻接矩阵)存储表示------ */#define INFINITY INT_MAX//用整型最大值代替∞#define MAX_VERTEX_NUM 20 //最大顶点数#define MAX_NAME 5 //顶点字符串的最大长度+1#define MAX_INFO 20 //相关信息字符串的最大长度+1#define MAXSIZE 100typedef enum { MDG, MDN, UDG, UDN } MGraphKind; //有向图,有向网,无向图,无向网typedef int VRType; //顶点关系类型,对无权图,用1或0typedef char InfoType; //弧信息类型typedef char VertexType[MAX_NAME]; //顶点类型typedef struct ArcCell{VRType adj; //表示相邻否;对带权图,则为权值类型InfoType *info; //弧相关信息的指针}ArcCell, AdjMatrix[MAX_VERTEX_NUM][MAX_VERTEX_NUM];typedef struct{VertexType vexs[MAX_VERTEX_NUM];//顶点向量AdjMatrix arcs; //邻接矩阵int vexnum, arcnum; //图的当前顶点数和弧数MGraphKind kind; //图种类标志}MGraph;/* ------图的邻接表存储表示------ */typedef enum{ ADG, ADN, AUDG, AUDN }ALGraphKind; // {有向图,有向网,无向图,无向网}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; //图的当前顶点数和弧数ALGraphKind kind; //图的种类标志}ALGraph; //邻接表结构描述int visited[MAX_VERTEX_NUM]; //访问标志数组(全局量)Status(*VisitFunc)(VertexType); //函数变量#endif/* ADT_H_ */3.头文件"DataStructure_Graph.h"中部分函数定义如下:#include<stdio.h>#include<malloc.h>#include"ADT.h"#include"DataStructure_StackQueue.h" //数据结构第三章栈和队列相关函数的定义及声明/************************************************************* 功能函数声明区************************************************************/int LocateVex(MGraph G, VertexType u); //若G中存在顶点u,则返回该顶点在图中的位置,否则返回1Status CreateGraph(MGraph &G); //采用数组(邻接矩阵)表示法,构造图GStatus CreateDG(MGraph &G); //采用数组(邻接矩阵)表示法,构造有向图GStatus CreateDN(MGraph &G); //采用数组(邻接矩阵)表示法,构造有向网GStatus CreateUDN(MGraph &G); //采用数组(邻接矩阵)表示法,构造无向图GStatus CreateUDG(MGraph &G); //采用数组(邻接矩阵)表示法,构造无向网GStatus DestroyGraph(MGraph &G); //销毁图GStatus DisplayGraph(MGraph G); //输出邻接矩阵表示图Gvoid DFSTraverse(MGraph G, Status(*Visit)(int v)); //深度优先搜索邻接矩形表示的图Gint LocateVex(ALGraph G, VertexType u); //若G中存在顶点u,则返回该顶点在图中的位置,否则返回1Status CreateGraph(ALGraph &G); //采用邻接表存储结构,构造没有相关信息的4种图G Status DestroyGraph(ALGraph &G); //销毁图GVertexType* GetVex(ALGraph G, int v); //返回顶点v的值int FirstAdjVex(ALGraph G, VertexType v); //返回v的第一个邻接顶点的序号.若没有邻接顶点,返回-1Status DisplayGraph(ALGraph G); //输出邻接表表示图Gvoid DFSTraverse(ALGraph G, Status(*Visit)(int v));//深度优先搜索邻接表表示的图Gint exist_path_DFS(ALGraph G, int i, int j); //判断邻接表方式存储的有向图G是否存在顶点i到j路径/************************************************************* 功能函数定义区************************************************************//********************邻接矩阵表示********************//** 函数原型:int LocateVex(MGraph &G, VertexType u)* 函数功能:若G中存在顶点u,则返回该顶点在图中的位置,否则返回1* 入口参数:已存在的图G,与G中顶点类型相同的顶点u* 出口参数:顶点在图中的位置,否则返回-1*/int LocateVex(MGraph G, VertexType u){int i = 0;for (int i = 0; i < G.vexnum; ++i)if (strcmp(u, G.vexs[i]) == 0)return i;return -1;} //LocateVex/** 函数原型:Status CreateGraph( MGraph &G )* 函数功能:采用数组(邻接矩阵)表示法,构造图G* 入口参数:图G* 出口参数:返回函数结果状态*/Status CreateGraph(MGraph &G){cout << "请输入图G的类型(有向图:0,有向网:1,无向图:2,无向网:3):";//cin >> kind;scanf_s("%d", &G.kind); // 自定义输入函数,读入一个随机值switch (G.kind){case MDG: return CreateDG(G); // 构造有向图Gcase MDN: return CreateDN(G); // 构造有向网Gcase UDG: return CreateUDG(G); // 构造无向图Gcase UDN: return CreateUDN(G); // 构造无向网Gdefault : return ERROR;}return OK;} // CreateGraph/** 函数原型:Status CreateDG(MGraph &G)* 函数功能:采用数组(邻接矩阵)表示法,构造有向图G* 入口参数:图G* 出口参数:返回函数结果状态*/Status CreateDG(MGraph &G){int IncInfo;char s[MAX_INFO], *info;VertexType va, vb; //顶点类型cout << "请输入有向图G的顶点数,弧数,弧是否含其他信息(是:1,否:0 以空格作为间隔):";cin >> G.vexnum >> G.arcnum >> IncInfo;cout << "请输入" << G.vexnum << "个顶点的值(少于" << MAX_NAME << "个字符):" << endl;for (int i = 0; i < G.vexnum; ++i) //构造顶点向量cin >> G.vexs[i];for (int i = 0; i < G.vexnum; ++i) //初始化邻接矩阵{for (int j = 0; j < G.vexnum; ++j){G.arcs[i][j].adj = 0;G.arcs[i][j].info = NULL;}}cout << "请输入" << G.arcnum << "条弧的弧尾弧头(以空格作为间隔):" << endl; for (int i = 0; i < G.arcnum; ++i){cin >> va >> vb;int m = LocateVex(G, va);if (m < 0)cout << "在图G中未找到" << va << endl;int n = LocateVex(G, vb);if (n < 0)cout << "在图G中未找到" << vb << endl;G.arcs[m][n].adj = 1; //有向图if (IncInfo){cout << "请输入该弧的相关信息(少于" << MAX_INFO << "个字符):";cin >> s;int length = strlen(s);if (length){info = new char[length + 1];strcpy_s(info,length + 1,s);G.arcs[m][n].info = info; //有向}}}G.kind = MDG;return OK;} // CreateDG/** 函数原型:Status DisplayGraph(MGraph G)* 函数功能:输出邻接矩阵表示图G* 入口参数:图G* 出口参数:返回函数结果状态*/Status DisplayGraph(MGraph G){const int MAX_STR_G = 8;const int MAX_STR_ARC = 5;char s[MAX_STR_G], s1[MAX_STR_ARC];switch (G.kind){case MDG: strcpy_s(s, MAX_STR_G, "有向图\0");strcpy_s(s1, MAX_STR_ARC, "弧\0");break;case MDN: strcpy_s(s, MAX_STR_G, "有向网\0");strcpy_s(s1, MAX_STR_ARC, "弧\0");break;case UDG: strcpy_s(s, MAX_STR_G, "无向图\0");strcpy_s(s1, MAX_STR_ARC, "边\0");break;case UDN: strcpy_s(s, MAX_STR_G, "无向网\0");strcpy_s(s1, MAX_STR_ARC, "边\0");}printf(" %sG的信息:%d个顶点 %d条%s\n", s,G.vexnum, G.arcnum, s1); for (int i = 0; i < G.vexnum; ++i) //输出G.vexsprintf("G.vexs[%d]=%s\n", i, G.vexs[i]);printf("G.arcs.adj:\n"); // 输出G.arcs.adjfor (int i = 0; i < G.vexnum; i++){for (int j = 0; j < G.vexnum; j++)printf("%6d", G.arcs[i][j].adj);printf("\n");}printf(":\n"); //输出printf("顶点1(弧尾) 顶点2(弧头) 该%s信息:\n", s1);if (G.kind < 2) //有向{for (int i = 0; i < G.vexnum; i++)for (int j = 0; j < G.vexnum; j++){if (G.arcs[i][j].adj){printf("%5s --->%5s ", G.vexs[i], G.vexs[j]);if (G.arcs[i][j].info)printf("%7s\n", G.arcs[i][j].info);elseprintf(" null\n");}}}else//无向{for (int i = 0; i<G.vexnum; i++)for (int j = i + 1; j < G.vexnum; j++){if (G.arcs[i][j].adj){printf("%5s --->%5s ", G.vexs[i], G.vexs[j]);if (G.arcs[i][j].info)printf("%7s\n", G.arcs[i][j].info);elseprintf(" null\n");}}}return OK;} //DisplayGraph/**************************图的邻接表存储**************************/ /** 函数原型:int LocateVex(ALGraph G, VertexType u)* 函数功能:若G中存在顶点u,则返回该顶点在图中的位置,否则返回1* 入口参数:已存在的图G,与G中顶点类型相同的顶点u* 出口参数:顶点在图中的位置,否则返回-1*/int LocateVex(ALGraph G, VertexType u){int i;for (i = 0; i<G.vexnum; ++i)if (strcmp(u, G.vertices[i].data) == 0)return i;return -1;} //LocateVex/** 函数原型:CreateGraph(ALGraph &G)* 函数功能:采用邻接表存储结构,构造没有相关信息的图G(用一个函数构造4种图) * 入口参数:图G* 出口参数:返回函数结果状态*/Status CreateGraph(ALGraph &G){int w; //权值VertexType va, vb;ArcNode *p;printf("请输入图的类型(有向图:0,有向网:1,无向图:2,无向网:3): ");scanf_s("%d", &G.kind);printf("请输入图的顶点数边数(以空格分隔): ");cin >> G.vexnum >> G.arcnum;printf("请输入%d个顶点的值(少于%d个字符):\n", G.vexnum, MAX_NAME);for (int i = 0; i<G.vexnum; ++i) //构造顶点向量{cin >> G.vertices[i].data;G.vertices[i].firstarc = NULL;}if (G.kind == 1 || G.kind == 3) //网printf("请顺序输入每条弧(边)的权值、弧尾和弧头(以空格作为间隔):\n"); else//图printf("请顺序输入每条弧(边)的弧尾和弧头(以空格作为间隔):\n");for (int k = 0; k<G.arcnum; ++k) //构造表结点链表{if (G.kind == 1 || G.kind == 3) //网cin >> w >> va >> vb;else//图cin >> va >> vb;int m = LocateVex(G, va); //弧尾int n = LocateVex(G, vb); //弧头p = (ArcNode*)malloc(sizeof(ArcNode));p->adjvex = n;if (G.kind == 1 || G.kind == 3) //网{p->info = (char *)malloc(sizeof(char));*(p->info) = w;}elsep->info = NULL; //图p->nextarc = G.vertices[m].firstarc; //插在表头G.vertices[m].firstarc = p;if (G.kind >= 2) //无向图或网,产生第二个表结点{p = (ArcNode*)malloc(sizeof(ArcNode));p->adjvex = m;if (G.kind == 3) //无向网{p->info = (char*)malloc(sizeof(char));*(p->info) = w;}elsep->info = NULL; //无向图p->nextarc = G.vertices[n].firstarc; //插在表头G.vertices[n].firstarc = p;}}return OK;} //CreateGraph/** 函数原型:int exist_path_DFS(ALGraph G, int i, int j)* 函数功能:判断邻接表方式存储的有向图G是否存在顶点i到j路径* 入口参数:图G存在,v是G中某个顶点* 出口参数:返回v的第一个邻接顶点的序号*/int exist_path_DFS(ALGraph G, int i, int j){ArcNode *p;if (i == j)return 1; //找到了一条路径,且长度符合要求else{visited[i] = 1;for (p = G.vertices[i].firstarc; p; p = p->nextarc){int index = p->adjvex;if (!visited[index] && exist_path_DFS(G, index, j))return 1; //剩余路径长度减一}visited[i] = 0; //允许曾经被访问过的结点出现在另一条路径中}return 0; //没找到}//exist_path_DFS运行结果邻接矩阵结构表示的图GAC EBFD邻接表结构表示的图G从上图看出从顶点A到顶点D有路径相连从上图看出从顶点C到顶点E没有路径相连实验总结1、此次实验完成了对图的邻接矩阵和邻接表这两种结构的存储、显示,以及邻接表存储结构下对图进行深度优先搜索判断是否存在指定位置的路径。