图的深度和广度优先搜索遍历
吉林工业职业技术学院(数据结构实训报告)(2012~ 2013 学年第1 学期)
实训地点:软件开发实训室
指导教师:赵秀艳、刘文宏
专业班级:计算机3111
学生姓名:36号折春雨
2012年12月13日
目录
实训项目 (1)
实训目的 (1)
设计分析 (1)
设计方案 (2)
详细设计 (4)
运行调试 (12)
实训心得 (15)
参考文献 (16)
数据结构实训报告
实训项目
1. 个人项目:图的深度和广度优先搜索遍历
问题描述:给定一个无向图,利用邻接矩阵或邻接表进行存储,然后按照深度和广度进行遍历。
要求:以吉林省的城市:白城、松原、长春、公主岭、四平、辽源、吉林市、通化、白山、延吉所构成的地理图为无向图。求以吉林市为出发点深度和广度优先搜索遍历序列。
2. 小组项目:学生成绩管理系统
问题描述:编写一个学生成绩管理系统,实现计算每个学生的总分、平均分,班级的总分、平均分,按分数高低排序。包含插入、删除、修改、查询、显示模块。
要求:成绩包括本学期所开设的课程(数据结构、计算机网络、数据库原理、……),采用菜单程序编写。包含插入、删除、修改、查询、显示模块。
实训目的
通过本次实训,能够进一步巩固、掌握程序设计基础和数据结构课程的基本知识、基本技能。运用算法分析与程序设计的一般方法进行实际项目的开发。本项目需要具备熟练的数组和线性表知识,具备程序编写、调试的基本能力,具有一定的文字表达和报告撰写能力,具备办公软件使用能力。
设计分析
1. 个人项目:图的深度和广度优先搜索遍历
图示一种较线性表和树更复杂的结构,在无向图图的结构中,节点之间的关系可以使任意的,无向图是指任意两个定点之间的连线时没有方向的,图中两个数据元素之间都可以相关。所以,首先选择适合的存储结构完成图的建立,我们采用栈来存储。其次是建立图的邻接矩阵存储,邻接矩阵表示法也称为数组表示法,就是用一位数组存储途
中的定点信息。最后,完成图的深度和广度优先遍历。深度优先遍历就是从某个顶点出发,沿着它的一条路径不断深入地访问图上的顶点,并按访问的次序输出所有顶点。广度优先遍历类似于图的按层次遍历的过程。然后输出遍历序列。
2. 小组项目:学生成绩管理系统
学生成绩管理系统主要功能是对学生信息进行加工和处理,根据任务要求,系统要完成学生信息的采集,信息的维护,信息查询和报表输出等操作,因此可将系统的开发过程分为系统设计,学生数据结构设计,设计系统框架,学生数据的存储与重用,系统维护设计,数据查询,数据统计,报表输出八个任务。
首先确定要处理的对象并对其进行描述,即画出数据结构列表,班级学生成绩管理系统要处理的对象是学生。然后按照系统功能的总体要求进行程序编制。整个系统还需要具有以下功能:维护功能,查询功能,统计功能,报表输出功能,存储和重用功能。
设计方案
1. 个人项目:图的深度和广度优先搜索遍历
把问题分成三个部分:一是建立无向图,运用栈来建立;二是将无向图进行邻接矩阵存储;三是将图进行深度和广度优先遍历。
实现第一个算法思想:建立一个队列,将无向图的节点数和边数输入,再将节点的内容和边指针输入,建立无向图。
实现第二个算法思想:将建立好的无向图进行邻接矩阵存储,即矩阵的形式。
实现第三个算法思想:无向图的深度优先遍历是选定任意一个节点作为起点,依次遍历和此节点有联系的节点,直至最后没有在与此节点有联系的节点为止。如果图中还有未被访问的节点,则选定任意未被遍历的节点作为起始点,直至图中所有节点都被遍历。
无向图的广度优先遍历类似于二叉树的按层次遍历。假设从图中某定点V出发,在访问了V之后一次访问V的哥哥未曾访问过的邻接点,然后分别从这些邻接点出发一次访问它们的邻接点,直至图中所有节点均被访问
2. 小组项目:学生成绩管理系统如图1所示
图一学生成绩管理界面
(1)建立一个明了的管理菜单。
<1>录入学生成绩
<2>导入学生成绩
<3>查询学生成绩
<4>删除学生记录、追加学生记录
<5>显示学生记录
<6>统计学生成绩
<7>保存输入记录
<8>成绩进行排序
<9>退出。
(2)使操作人员很容易的完成对学生成绩的查询、修改、添加、保存和导入。
(3)在统计与排序这一模块中又可分为多个可操作模块,大大增加了此系统的功能,如统计学生成绩中可分为按个人总分和平均分统计、按单科平均分统计、按总分最高分和总分最低分统计;而在排序这一模块中又分为按学生学号、学生姓名、学生各单科成绩排序,大大减少了工作量。
(4)和以往系统不同,在它的模块中新增加拉保存与导入记录这两个模块,运用这两个模块可以将外界数据导入系统中或将本系统中的数据导入外界进行保存工作,以防数据丢失。
(5)对要查询的数据要有准确性。
(6)使操作人员很容易的完成对学生成绩的查询,修改和添加。
(7)对要查询的数据要有准确性。
数据结构定义:
定义主函数main( );在main( )里定义变量,使用do-while设计程序的容错性,定义被调函数fun1、fun2、fun3、fun4、fun5、fun6和fun7判断所要进行的操作。
if(choose==1||choose==2||choose==3||choose==4||choose==5
||choose==6||choose==7||choose==8||choose==0)
switch(choose)
{
case 1:fun1(); break;//添加
case 2:fun2(); break;//计算个人总分、平均分,班级总分、平均分
case 3:fun3(); break; //排序
case 4:fun4(); break; //查询
case 5:fun5(); break; //修改
case 6:fun6();break; //删除
case 7:fun7();break; //插入
}
详细设计
1. 个人项目:图的深度和广度优先搜索遍历
源程序代码如下:
#define TRUE 1
typedef long VertexType;/*节点数据为字符型*/
int visited[MAX_VERTEX_NUM];/*这个数组用于记录各结点的访问状态*/
……
void CreateGraph(ALGraph &G)/*建立图的邻接表存储结构,创建无向图*/
int i, j = 0, k = 0;
char head, tail;/*边的头和尾*/
ArcNode *p;
cout<<"请输入图的结点数和边数:";
cin>>G.vexnum>>G.arcnum;/*输入图的结点数目和边的数目*/
cout<<"请依次输入图结点的数据(英文字符):";
for(i=0; i < G.vexnum; i++)
cin>>G.vertices[i].data;/*读入顶点信息*/
for(i=0;i G.vertices[i].firstarc=NULL;/*初始化顶点表中的头指针为空*/ cout<<"请依次输入一条边所依附的两个顶点(例:a b):"< for(i=0; i < G.arcnum; i++)/*读入各条边信息,建立邻接表*/ { cout< cin>>tail>>head;/*输入边的首尾结点的数据*/ while (head != G.vertices[j].data) j++;/*找到弧头结点的序号*/ while (tail != G.vertices[k].data) k++;/*找到弧尾结点的序号*/ p=new ArcNode; ArcNode *q=G.vertices[k].firstarc; if(q!=NULL)/*如果弧尾顶点的边表中有结点,则将弧头结点号插入到边表的最后*/ void DFS(ALGraph G, int v)/*以第v个结点开始深度搜索*/ { ArcNode *p; cout< visited[v]=TRUE;/*标记v已访问*/ p=G.vertices[v].firstarc;/*取第v个顶点的边表头指针*/ while(p)/*依次搜索第v个顶点的邻接点*/ if(!visited[p->adjvex])/*若邻接点尚未被访问*/ DFS(G,p->adjvex);/*则以临界点为出发点向纵深搜索*/ p=p->nextarc;/*找第v个顶点的下一邻接点*/ } } void DFSGraph(ALGraph G, int k)/*深度优先遍历*/ { int j; for(j=0; j visited[j] = FALSE;/*初始化访问状态数组*/ for(j=0; j if(!visited[j])/*以第j个结点为源点开始DFS搜索*/ DFS(G, j); } void main() { cout<<"----按邻接表存储的图的遍历----"< cout<<"操作菜单(按0退出):"< cout<<"1. 图的建立"< cout<<"2. 深度优先遍历图"< cout<<"3. 广度优先遍历图"< cout<<"0. 退出"< int i,j; int CreatedGraph=0; /*标识图是否已建立*/ char src; ALGraph G; ArcNode *p; while(1) …… cout<<"请选择深度遍历的初始点:"; cin>>src; for(j=0;j if(src == G.vertices[j].data)/*找到初始结点的序号*/ …… 2. 小组项目:学生成绩管理系统 int totle; int ave; char neartime[10];//最近更新时间 }; typedef struct node { struct student data; struct node *next; }Node,*Link; void menu() { printf("***************************************************************** ***************"); printf("\t1输入学生资料\t\t\t\t\t2删除学生资料\n"); printf("\t3查询学生资料\t\t\t\t\t4修改学生资料\n"); printf("\t5显示学生资料\t\t\t\t\t6统计学生成绩\n"); printf("\t7排序学生成绩\t\t\t\t\t8保存学生资料\n"); printf("\t9获取帮助信息\t\t\t\t\t0退出系统\n"); printf("***************************************************************** ***************\n"); } void printstart() { printf("-----------------------------------------------------------------------\n"); } void Wrong() { printf("\n=====>提示:输入错误!\n"); } void Nofind() { printf("\n=====>提示:没有找到该学生!\n"); } void printc() // 本函数用于输出中文 { printf("学号\t 姓名性别英语数学C语言总分平均分\n"); } void printe(Node *p)//本函数用于输出英文 { printf("%-12s%s\t%s\t%d\t%d\t%d\t %d\t %d\n",p->data.num,p->https://www.360docs.net/doc/f210496518.html,,p->data.sex, p->data.egrade,p->data.mgrade,p->data.cgrade,p->data.totle,p->data.ave); } Node* Locate(Link l,char findmess[],char nameornum[]) //该函数用于定位连表中符合要求的接点,并返回该指针 { Node *r; if(strcmp(nameornum,"num")==0) //按学号查询 { r=l->next; while(r) { if(strcmp(r->data.num,findmess)==0) return r; r=r->next; } } else if(strcmp(nameornum,"name")==0) //按姓名查询 { r=l->next; while(r) { if(strcmp(r->https://www.360docs.net/doc/f210496518.html,,findmess)==0) return r; r=r->next; } } return 0; } void Add(Link l) //增加学生 { Node *p,*r,*s; char num[10]; r=l; s=l->next; while(r->next!=NULL) r=r->next; //将指针置于最末尾 while(1) { printf("请你输入学号(以'0'返回上一级菜单:)"); scanf("%s",num); if(strcmp(num,"0")==0) break; while(s) { if(strcmp(s->data.num,num)==0) { printf("=====>提示:学号为'%s'的学生已经存在,若要修改请你选择'4 修改'!\n",num); printstart(); printc(); printe(s); printstart(); printf("\n"); return; } s=s->next; } p=(Node *)malloc(sizeof(Node)); strcpy(p->data.num,num); printf("请你输入姓名:"); scanf("%s",p->https://www.360docs.net/doc/f210496518.html,); getchar(); printf("请你输入性别:"); scanf("%s",p->data.sex); getchar(); printf("请你输入c语言成绩:"); scanf("%d",&p->data.cgrade); getchar(); printf("请你输入数学成绩:"); scanf("%d",&p->data.mgrade); getchar(); printf("请你输入英语成绩:"); scanf("%d",&p->data.egrade); getchar(); p->data.totle=p->data.egrade+p->data.cgrade+p->data.mgrade; p->data.ave=p->data.totle / 3; //信息输入已经完成 p->next=NULL; r->next=p; r=p; shoudsave=1; } } void Qur(Link l) //查询学生 { int sel; char findmess[20]; if(!l->next) { printf("\n=====>提示:没有资料可以查询!\n"); return; } printf("\n=====>1按学号查找\n=====>2按姓名查找\n"); scanf("%d",&sel); if(sel==1)//学号 { printf("请你输入要查找的学号:"); scanf("%s",findmess); p=Locate(l,findmess,"num"); if(p) { printf("\t\t\t\t查找结果\n"); printstart(); printc(); printe(p); printstart(); } else Nofind(); } else if(sel==2) //姓名 { printf("请你输入要查找的姓名:"); scanf("%s",findmess); p=Locate(l,findmess,"name"); if(p) { printf("\t\t\t\t查找结果\n"); printstart(); printe(p); printstart(); } else Nofind(); } else Wrong(); 使用说明 1. 个人项目:图的深度和广度优先搜索遍历 本程序在c++6.0环境下运行通过。运行后,根据提示输入数据即可。可以输入无向图的节点数和边数,然后输入节点信息,就可以将这个图进行存储,最后输出的是深度和广度优先遍历后的结果。 2. 小组项目:学生成绩管理系统 本程序在c++6.0环境下运行通过。运行后,根据提示输入数据即可。可以进行学生成绩信息的录入,导入,查询,删除,显示,统计,保存,排序。可以很方便的对学生信息进行加工处理。 运行调试 1. 个人项目:图的深度和广度优先搜索遍历 运行可执行文件学生成绩管理.c或在c++6.0下同时按住ctrl+F9运行学生成绩管理.c 文件即可。 运行实例如下: 测试数据一:如图2、3所示 图2:图的建立和邻接矩阵存储 图3:图的深度和广度优先遍历 2. 小组项目:学生成绩管理系统 测试数据一:如图4所示 图4:学生成绩管理系统操作一测试数据二:如图5所示 图5:操作3查询学生资料 实训心得 通过两周的实训,使我对程序设计基础和数据结构两门课程的基本知识有了进一步的理解,也对团队合作有了更深刻的感悟。个人的力量是有限的,大家的力量才是强大的。特别数组和顺序表知识尤为深刻,学到了程序设计的一般方法和步骤,对于曾经在课堂上没有熟练掌握,甚至是没有掌握的知识,在实训周里都不同程度的得到了巩固。通过实训,我在算法分析与设计、程序编制与调试、报告撰写等方面有了极大的收获,有助于培养自己良好的编程思想,提高了自己的操作能力、专业能力和职业能力,为今后课程的学习和毕业设计打下了基础。虽然在实训期间我遇到了很多问题,但是通过老师的指点与同学之间的探讨,我们都在愉快中解决了出现的问题,让我感觉到了程序设计中的奥妙与乐趣。已经大二的我们,再过不到一年,就要毕业了,面临是继续深造,还是就业的压力,我想我们更应该把握这段时间,充实、完善自我,从自身知识入手,在书本和实践中不断完善自我,将数据结构发展到软件编程等方向,为将来工作和生活奠定坚实基础。 参考文献 [1] 张红霞. 数据结构与教程. 北京理工大学出版社 [2] 付百文. 数据结构实训教程. 科学出版社 [3]王静. 数据结构及其应用. 东南大学出版社 [4] 吴伟民. 数据结构题集. 清华大学出版社 [5] 谭浩强. C程序设计. 清华大学出版 [6] http://www.123.45.68.9 合肥学院 计算机科学与技术系 课程设计报告 2013~2014学年第二学期 课程数据结构与算法 课程设计名称图的深度优先遍历算法的实现 学生姓名陈琳 学号1204091022 专业班级软件工程 指导教师何立新 2014 年9 月 一:问题分析和任务定义 涉及到数据结构遍会涉及到对应存储方法的遍历问题。本次程序采用邻接表的存储方法,并且以深度优先实现遍历的过程得到其遍历序列。 深度优先遍历图的方法是,从图中某顶点v 出发: (1)访问顶点v ; (2)依次从v 的未被访问的邻接点出发,对图进行深度优先遍历;直至图中和v 有路径相通的顶点都被访问; (3)若此时图中尚有顶点未被访问,则从一个未被访问的顶点出发,重新进行深度优先遍历,直到图中所有顶点均被访问过为止。 二:数据结构的选择和概要设计 设计流程如图: 图1 设计流程 利用一维数组创建邻接表,同时还需要一个一维数组来存储顶点信息。之后利用创建的邻接表来创建图,最后用深度优先的方法来实现遍历。 图 2 原始图 1.从0开始,首先找到0的关联顶点3 2.由3出发,找到1;由1出发,没有关联的顶点。 3.回到3,从3出发,找到2;由2出发,没有关联的顶点。 4.回到4,出4出发,找到1,因为1已经被访问过了,所以不访问。 所以最后顺序是0,3,1,2,4 三:详细设计和编码 1.创建邻接表和图 void CreateALGraph (ALGraph* G) //建立邻接表函数. { int i,j,k,s; char y; EdgeNode* p; //工作指针. printf("请输入图的顶点数n与边数e(以逗号做分隔符):\n"); scanf("%d,%d",&(G->n),&(G->e)); scanf("%c",&y); //用y来接收回车符. for(s=0;s #include 上机实验报告 学院:计算机与信息技术学院 专业:计算机科学与技术(师范)课程名称:数据结构 实验题目:深度优先遍历(邻接矩阵)班级序号:师范1班 学号:201421012731 学生姓名:邓雪 指导教师:杨红颖 完成时间:2015年12月25号 一、实验目的: 1﹒掌握图的基本概念和邻接矩阵存储结构。 2﹒掌握图的邻接矩阵存储结构的算法实现。 3﹒掌握图在邻接矩阵存储结构上遍历算法的实现。 二、实验环境: Windows 8.1 Microsoft Visual c++ 6.0 二、实验内容及要求: 编写图的深度优先遍历邻接矩阵算法。建立图的存储结构,能够输入图的顶点和边的信息,并存储到相应存储结构中,而后输出图的邻接矩阵。 四、概要设计: 深度优先搜索遍历类似于树的先根遍历,是树的先根遍历的推广。假设初始状态是图中所有的顶点未曾被访问,则深度优先遍历可从图的某个顶点V出发,访问此顶点,然后依次从V的未被访问的邻接点出发深度优先遍历图,直至图中所有和V有路径相通的顶点都被访问到;若此时图中尚有顶点未被访问,则另选图中的一个未被访问的顶点,重复上述过程,直至图中所有顶点都被访问到为止。 以图中无向图G4为例,深度优先遍历图的过程如图所示。假设从顶点V1出发进行搜索,在访问了顶点V1后,选择邻接点V2。因为V2未曾访问,则从V2出发进行搜索。依次类推,接着从V4,V8,V5出发进行搜索。在访问了V5之后,由于V5的邻接点已都被访问,则搜索回到V8。由于同样的理由,搜索继续回到V4,V2直至V1,此时由于V1的另一个邻接点为被访问,则搜索又从V1到V3,再继续进行下去。由此得到顶点的访问序列为: V1 V2 V4 V8 V5 V3 V6 V7 五、代码 #include 一.实验目的 熟悉图的存储结构,掌握用单链表存储数据元素信息和数据元素之间的关系的信息的方法,并能运用图的深度优先搜索遍历一个图,对其输出。 二.实验原理 深度优先搜索遍历是树的先根遍历的推广。假设初始状态时图中所有顶点未曾访问,则深度优先搜索可从图中某个顶点v出发,访问此顶点,然后依次从v的未被访问的邻接点出发深度优先遍历图,直至图中所有与v有路径相通的顶点都被访问到;若此时图中尚有顶点未被访问,则另选图中一个未曾访问的顶点作起始点,重复上述过程,直至图中所有顶点都被访问到为止。 图的邻接表的存储表示: #define MAX_VERTEX_NUM 20 #define MAXNAME 10 typedef char VertexType[MAXNAME]; typedef struct ArcNode{ int adjvex; struct ArcNode *nextarc; }ArcNode; typedef struct VNode{ VertexType data; ArcNode *firstarc; }VNode,AdjList[MAX_VERTEX_NUM]; typedef struct{ AdjList vertices; int vexnum,arcnum; int kind; }ALGraph; 三.实验内容 编写LocateVex函数,Create函数,print函数,main函数,输入要构造的图的相关信息,得到其邻接表并输出显示。 四。实验步骤 1)结构体定义,预定义,全局变量定义。 #include"stdio.h" #include"stdlib.h" #include"string.h" #define FALSE 0 #define TRUE 1 #define MAX 20 typedef int Boolean; #define MAX_VERTEX_NUM 20 #include 华北水利水电学院数据结构实验报告 20 10 ~20 11 学年第一学期2008级计算机专业 班级:107学号:200810702姓名:王文波 实验四图的应用 一、实验目的: 1.掌握图的存储结构及其构造方法 2.掌握图的两种遍历算法及其执行过程 二、实验内容: 以邻接矩阵或邻接表为存储结构,以用户指定的顶点为起始点,实现无向连通图的深度优先及广度优先搜索遍历,并输出遍历的结点序列。 提示:首先,根据用户输入的顶点总数和边数,构造无向图,然后以用户输入的顶点为起始点,进行深度优先和广度优先遍历,并输出遍历的结果。 三、实验要求: 1.各班学号为单号的同学采用邻接矩阵实现,学号为双号的同学采用邻接表实现。 2.C/ C++完成算法设计和程序设计并上机调试通过。 3.撰写实验报告,提供实验结果和数据。 4.写出算法设计小结和心得。 四、程序源代码: #include { int nData; QueueNode* next; }; struct QueueList { QueueNode* front; QueueNode* rear; }; void EnQueue(QueueList* Q,int e) { QueueNode *q=new QueueNode; q->nData=e; q->next=NULL; if(Q==NULL) return; if(Q->rear==NULL) Q->front=Q->rear=q; else { Q->rear->next=q; Q->rear=Q->rear->next; } } void DeQueue(QueueList* Q,int* e) { if (Q==NULL) return; if (Q->front==Q->rear) { *e=Q->front->nData; Q->front=Q->rear=NULL; } else { *e=Q->front->nData; Q->front=Q->front->next; } } //创建图 void CreatAdjList(Graph* G) { int i,j,k; edgenode* p1; edgenode* p2; 有两种常用的方法可用来搜索图:即深度优先搜索和广度优先搜索。它们最终都会到达所有 连通的顶点。深度优先搜索通过栈来实现,而广度优先搜索通过队列来实现。 深度优先搜索: 深度优先搜索就是在搜索树的每一层始终先只扩展一个子节点,不断地向纵深前进直到不能再前进(到达叶子节点或受到深度限制)时,才从当前节点返回到上一级节点,沿另一方向又继续前进。这种方法的搜索树是从树根开始一枝一枝逐渐形成的。 下面图中的数字显示了深度优先搜索顶点被访问的顺序。 "* ■ J 严-* 4 t C '4 --------------------------------- --- _ 为了实现深度优先搜索,首先选择一个起始顶点并需要遵守三个规则: (1) 如果可能,访问一个邻接的未访问顶点,标记它,并把它放入栈中。 (2) 当不能执行规则1时,如果栈不空,就从栈中弹出一个顶点。 (3) 如果不能执行规则1和规则2,就完成了整个搜索过程。 广度优先搜索: 在深度优先搜索算法中,是深度越大的结点越先得到扩展。如果在搜索中把算法改为按结点的层次进行搜索,本层的结点没有搜索处理完时,不能对下层结点进行处理,即深度越小的结点越先得到扩展,也就是说先产生的结点先得以扩展处理,这种搜索算法称为广度优先搜索法。 在深度优先搜索中,算法表现得好像要尽快地远离起始点似的。相反,在广度优先搜索中, 算法好像要尽可能地靠近起始点。它首先访问起始顶点的所有邻接点,然后再访问较远的区 域。它是用队列来实现的。 下面图中的数字显示了广度优先搜索顶点被访问的顺序。 实现广度优先搜索,也要遵守三个规则: ⑴ 访问下一个未来访问的邻接点,这个顶点必须是当前顶点的邻接点,标记它,并把它插入到队列中。(2)如果因为已经没有未访问顶点而不能执行规则1 *问题描述: 建立图的存储结构(图的类型可以是有向图、无向图、有向网、无向网,学生可以任选两种类型),能够输入图的顶点和边的信息,并存储到相应存储结构中,而后输出图的邻接矩阵。 1、邻接矩阵表示法: 设G=(V,E)是一个图,其中V={V1,V2,V3…,Vn}。G的邻接矩阵是一个他有下述性质的n阶方阵: 1,若(Vi,Vj)∈E 或 若图中每个顶点只含一个编号i(1≤i≤vnum),则只需一个二维数组表示图的邻接矩阵。此时存储结构可简单说明如下: type adjmatrix=array[1..vnum,1..vnum]of adj; 利用邻接矩阵很容易判定任意两个顶点之间是否有边(或弧)相联,并容易求得各个顶点的度。 对于无向图,顶点Vi的度是邻接矩阵中第i行元素之和,即 n n D(Vi)=∑A[i,j](或∑A[i,j]) j=1 i=1 对于有向图,顶点Vi的出度OD(Vi)为邻接矩阵第i行元素之和,顶点Vi 的入度ID(Vi)为第i列元素之和。即 n n OD(Vi)=∑A[i,j],OD(Vi)=∑A[j,i]) j=1j=1 用邻接矩阵也可以表示带权图,只要令 Wij, 若 2007-05-27 晴 //采用非递归深度优先遍历算法,可以将回溯法表示为一个非递归过程 #include }; private: int Bound(int i); void Backtrack(int i); int c; //背包容量 int n; //物品数 int *w; //物品重量数组int *p; //物品价值数组int cw; //当前重量 int cp; //当前价值 int bestp; //当前最优值int *bestx; //当前最优解int *x; //当前解 }; int Knap::Bound(int i) //装满背包 if(i<=n) b+=p/w*cleft; return b; } void Knap::Backtrack(int i) { if(i>n) { if(bestp *问题描述: 建立图的存储结构,能够输入图的顶点和边的信息,并存储到相应存储结构中,而后输出图的邻接矩阵。 1、邻接矩阵表示法: 设G=(V,E)是一个图,其中V={V1,V2,V3…,Vn}。G的邻接矩阵是一个他有下述性质的n阶方阵: 1,若(Vi,Vj)∈E 或 对于有向图,顶点Vi的出度OD(Vi)为邻接矩阵第i行元素之和,顶点Vi 的入度ID(Vi)为第i列元素之和。即 n n OD(Vi)=∑A[i,j],OD(Vi)=∑A[j,i]) j=1j=1 用邻接矩阵也可以表示带权图,只要令 Wij, 若 数据结构实验报告 实验四图的应用 一、实验题目: 图的应用——xx优先/xx优先搜索遍历 二、实验内容: 很多涉及图上操作的算法都是以图的遍历操作为基础的。试编写一个算法,实现图的深度优先和广度优先搜索遍历操作。 要求: 以邻接矩阵或邻接表为存储结构,以用户指定的顶点为起始点,实现连通无向图的深度优先及广度优先搜索遍历,并输出遍历的结点序列。(注: 学号为奇数的同学使用邻接矩阵存储结构实现,学号为偶数的同学使用邻接矩阵实现) 提示: 首先,根据用户输入的顶点总数和边数,构造无向图,然后以用户输入的顶点为起始点,进行深度优先、广度优先搜索遍历,并输出遍历的结果。 三、程序源代码: #include int adjvex;//该弧所指向的顶点的位置 struct ArcNode *nextarc;//指向下一条弧的指针 }ArcNode; typedef struct VNode{ int data;//顶点信息 ArcNode *firstarc;//指向第一条依附该顶点的弧的指针}VNode,AdjList[MAX_VERTEX_NUM]; typedef struct{ AdjList vertices; }ALGraph; typedef struct QNode{ int data; struct QNode *next; }QNode,*QuePtr; typedef struct{ QuePtr front;//队头指针 QuePtr rear;//队尾指针 }LinkQue; void InitQue(LinkQue &q){} void EnQue(LinkQue &q,int e){} int DeQue(LinkQue &q){int e; 算法设计:深度优先遍历和广度优先遍历实现 深度优先遍历过程 1、图的遍历 和树的遍历类似,图的遍历也是从某个顶点出发,沿着某条搜索路径对图中每个顶点各做一次且仅做一次访问。它是许多图的算法的基础。 深度优先遍历和广度优先遍历是最为重要的两种遍历图的方法。它们对无向图和有向图均适用。 注意: 以下假定遍历过程中访问顶点的操作是简单地输出顶点。 2、布尔向量visited[0..n-1]的设置 图中任一顶点都可能和其它顶点相邻接。在访问了某顶点之后,又可能顺着某条回路又回到了该顶点。为了避免重复访问同一个顶点,必须记住每个已访问的顶点。为此,可设一布尔向量visited[0..n-1],其初值为假,一旦访问了顶点Vi之后,便将visited[i]置为真。 -------------------------- 深度优先遍历(Depth-First Traversal) 1.图的深度优先遍历的递归定义 假设给定图G的初态是所有顶点均未曾访问过。在G中任选一顶点v为初始出发点(源点),则深度优先遍历可定义如下:首先访问出发点v,并将其标记为已访问过;然后依次从v出发搜索v的每个邻接点w。若w未曾访问过,则以w为新的出发点继续进行深度优先遍历,直至图中所有和源点v有路径相通的顶点(亦称为从源点可达的顶点)均已被访问为止。若此时图中仍有未访问的顶点,则另选一个尚未访问的顶点作为新的源点重复上述过程,直至图中所有顶点均已被访问为止。 图的深度优先遍历类似于树的前序遍历。采用的搜索方法的特点是尽可能先对纵深方向进行搜索。这种搜索方法称为深度优先搜索(Depth-First Search)。相应地,用此方法遍历图就很自然地称之为图的深度优先遍历。 2、深度优先搜索的过程 设x是当前被访问顶点,在对x做过访问标记后,选择一条从x出发的未检测过的 重庆邮电大学 数学大类专业 2008级《数学建模与数学实验》课程设计 设计题目:图的深度优先搜索遍历算法分析及其应用设计时间:2010.9.7-----2010.9. 12 班级: 学号: 指导教师: 图的深度优先搜索遍历算法分析及其应用 摘要:文章介绍了图论,图的基本概念及其图的表示方法。详细的分析了图中以邻接表为存储结构进行的图的深度优先搜索遍历的算法,并且在VC++环境中实现其算法的过程,对运行记过做了一定量的分析,最后介绍了基于该算法的一些应用。 关键词:图;深度优先搜索;遍历;算法 图论〔Graph Theory〕是数学的一个分支。它以图为研究对象。图论中的图是由若干给定的点及连接两点的线所构成的图形,这种图形通常用来描述某些事物之间的某种特定关系,用点代表事物,用连接两点的线表示相应两个事物间具有这种关系。 图(Graph)是一种较线性表和树更复杂的数据结构,图形结构中,结点之间的关系可以是任意的,图中任意两个数据元素之间都可能相关。因此,在研究有关图的问题时,要考虑图中每个顶点的信息,访问图中的各个顶点,而访问图中各个顶点的操作过程即使图的遍历,图的遍历算法是求解图的连通性问题,拓扑排序和求关键路径等算法的基础。 1图的三元组定义 图G是一个三元组由集合V,E和关联函数组成,记为:G=(V,E,W(G))。其中V是顶点的集合,表示V(G)={V1,V2,V3,……Vn},V(G)≠NULL。E是V中的点偶对的有穷集,表示为E(G)={e1,e2,e3……em},其中ei为 #include } cout<<"请输入顶点编号:"< 实验报告 一、实验目的和内容 1.实验目的 掌握图的邻接矩阵的存储结构;实现图的两种遍历:深度优先遍历和广度优先遍历。 2.实验内容 1.图的初始化; 2.图的遍历:深度优先遍历和广度优先遍历。 二、实验方案 程序主要代码: /// /// 深度优先搜索算法DFS = = = 1.首先选定图的类别(有向图、无向图),再选定图的存储结构,根据输入的顶点或者边建立图;并把相应的邻接表或者邻接矩阵输出; 2.根据已有的邻接矩阵或邻接表用递归方法编写深度优先搜索遍历算法,并输出遍历结果; [dfs.rar] - 深度优先搜索算法解决八码难题 [Draw1Doc.rar] - 简单的绘图程序,能画点,直线,多边形等,比较简单 = = = =这里的图的深度优先算法利用了栈来实现。 图的深度遍历原则: 1 如果有可能,访问一个领接的未访问的节点,标记它,并把它放入栈中。 2 当不能执行规则1 时,如果栈不为空,则从栈中弹出一个元素。 3 如果不能执行规则1 和规则2 时,则完成了遍历。 代码中的图使用的是Graph 图-邻接矩阵法来表示,其他的表示法请见:Graph 图-邻接表法 代码中的Stack为辅助结构,用来记载访问过的节点。栈的详细描述可以见:ArrayStack 栈,LinkedStack 栈。 Vertex表示图中的节点,其中包含访问,是否访问,清除访问标志的方法。 Graph.main:提供简单测试。代码可以以指定下标的节点开始作深度遍历。 代码比较简单,除了Graph.dsf(int i)深度优先遍历算法外没有过多注释。 = = = =深度优先搜索DFS 正如算法名称那样,深度优先搜索所遵循的搜索策略是尽可能“深”地搜索图。在深度优先搜索中,对于最新发现的顶点,如果它还有以此为起点而未探测到的边,就沿此边继续汉下去。当结点v的所有边都己被探寻过,搜索将回溯到发现结点v有那条边的始结点。这一过程一直进行到已发现从源结点可达的所有结点为止。如果还存在未被发现的结点,则选择其中一个作为源结点并重复以上过程,整个进程反复进行直到所有结点都被发现为止。 和宽度优先搜索类似,每当扫描已发现结点u的邻接表从而发现新结点v时,深度优先搜索将置v的先辈域π[v]为u。和宽度优先搜索不同的是,前者的先辈子图形成一棵树,而后者产生的先辈子图可以由几棵树组成,因为搜索可能由多个源顶点开始重复进行。因此深度优先搜索的先辈子图的定义也和宽度优先搜索稍有不同: Gπ=(V,Eπ),Eπ={(π[v],v)∈E:v∈V∧π[v]≠NIL} 深度优先搜索的先辈子图形成一个由数个深度优先树组成的深度优先森林。Eπ中的边称为树枝。 和宽度优先搜索类似,深度优先在搜索过程中也为结点着色以表示结点的状态。每个顶点开始均为白色,搜索中被发现时置为灰色,结束时又被置成黑色(即当其邻接表被完全检索之后)。这一技巧可以保证每一顶点搜索结束时只存在于一棵深度优先树上,因此这些树都是分离的。 除了创建一个深度优先森林外,深度优先搜索同时为每个结点加盖时间戳。每个结点v有两个时间戳:当结点v第一次被发现(并置成灰色)时记录下第一个时间戳d[v],当结束检查v 的邻接表时(并置v为黑色)记录下第二个时间截f[v]。许多图的算法中都用到时间戳,他们对推算深度优先搜索进行情况是很有帮助的。 下列过程DFS记录了何时在变量d[u]中发现结点u以及何时在变量f[u]中完成对结点u的检 #include "stdio.h" #include "stdlib.h" int visited[20]; #define MAX_VERTER_NUM 20 typedef char VertexType; typedef struct ArcNode{ int adjver; struct ArcNode *nextarc; //InfoType *info; }ArcNode; typedef struct VNode{ VertexType data; ArcNode *firstarc; }VNode,AdjList[MAX_VERTER_NUM]; typedef struct{ AdjList vertices; int vexnum,arcnum; int kind; }ALGraph; void GraphCreated(ALGraph *G) { int i,j,n; ArcNode *p,*q; printf("请输入顶点个数和弧数:\n"); scanf("%d%d",&G->vexnum,&G->arcnum); for(i=0;i #include 图的深度优先遍历算法课程设计报告
连通图深度优先遍历
深度优先遍历(邻接矩阵)
图的深度优先遍历实验报告
邻接矩阵的深度优先遍历
图的深度优先遍历和广度优先遍历
广度优先搜索和深度优先搜索
邻接矩阵表示图深度广度优先遍历
采用非递归深度优先遍历算法
邻接矩阵表示图_深度_广度优先遍历
实验四-图的应用――深度优先/广度优先搜索遍历
算法设计:深度优先遍历和广度优先遍历
图的深度优先搜索遍历算法分析及其应用
图深度优先搜索C++
图的深度和广度遍历 - 实验报告
深度优先搜索算法DFS
有向图的深度优先遍历
无向图的深度优先遍历序列