图的深度和广度优先搜索遍历

图的深度和广度优先搜索遍历
图的深度和广度优先搜索遍历

吉林工业职业技术学院(数据结构实训报告)(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;sn;s++) { printf("请输入下标为%d的顶点的元素:\n",s); scanf("%c",&(G->adjlist[s].vertex)); scanf("%c",&y); //用y来接收回车符.当后面要输入的是和单个字符有关的数据时候要存贮回车符,以免回车符被误接收。 G->adjlist[s].firstedge=NULL; } printf("请分别输入该图的%d条弧\n",G->e); for(k=0;ke;k++) { printf("请输入第%d条弧的起点和终点(起点下标,终点下标):\n",(k+1)); scanf("%d,%d",&i,&j); p=(EdgeNode*)malloc(sizeof(EdgeNode)); p->adjvex=j; p->next=G->adjlist[i].firstedge; G->adjlist[i].firstedge=p; } } 2.深度优先遍历 void DFS(ALGraph* G,int v) //深度优先遍历 { EdgeNode* p;

连通图深度优先遍历

#include #include #define MAXLEN 20 typedef struct node3 { int adjvex; struct node3 *next; }ARCNODE; typedef struct { char data; ARCNODE *firstarc; int id; } VEXNODE; typedef struct { VEXNODE vertices[MAXLEN]; int vexnum, arcnum; int kind; }ALGRAPH; int visited[MAXLEN]; ALGRAPH creat_graph() { ARCNODE *p; int i, s, d; ALGRAPH g; printf("\n\n输入顶点数和边数(用逗号隔开) : "); scanf("%d,%d", &s, &d);fflush(stdin); g.vexnum = s; /*存放顶点数在g.vexnum 中 */ g.arcnum = d; /*存放边点数在g.arcnum 中*/ printf("\n\n"); for(i = 0; i < g.vexnum; i++) /*输入顶点的值*/ {printf("输入顶点 %d 的值 : ", i + 1); scanf("%c", &g.vertices[i].data); fflush(stdin); g.vertices[i].firstarc = NULL;} printf("\n"); for(i = 0; i < g.arcnum; i++) {printf("输入第 %d 条边的起始顶点和终止顶点下标(用逗号隔开): ", i+1);

深度优先遍历(邻接矩阵)

上机实验报告 学院:计算机与信息技术学院 专业:计算机科学与技术(师范)课程名称:数据结构 实验题目:深度优先遍历(邻接矩阵)班级序号:师范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 #include #define n 8 #define e 9 typedef char vextype; typedef float adjtype; int visited[n]; //定义结构体

图的深度优先遍历实验报告

一.实验目的 熟悉图的存储结构,掌握用单链表存储数据元素信息和数据元素之间的关系的信息的方法,并能运用图的深度优先搜索遍历一个图,对其输出。 二.实验原理 深度优先搜索遍历是树的先根遍历的推广。假设初始状态时图中所有顶点未曾访问,则深度优先搜索可从图中某个顶点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 #include using namespace std; #define INFINITY 32767 #define MAX_VEX 50 #define OK 1 #define FALSE 0 #define TRUE 1 #define ERROR -1 bool *visited; //图的邻接矩阵存储结构 typedef struct { char *vexs; //动态分配空间存储顶点向量 int arcs[MAX_VEX][MAX_VEX]; //邻接矩阵 int vexnum, arcnum; //图的当前定点数和弧数 }Graph; //图G中查找顶点c的位置 int LocateVex(Graph G, char c) { for(int i = 0; i < G.vexnum; ++i) { if(G.vexs[i] == c) return i; } return ERROR; } //创建无向网 void CreateUDN(Graph &G){ //采用数组(邻接矩阵)表示法,构造无向图G cout << "请输入定点数和弧数:"; cin >> G.vexnum >> G.arcnum; cout << "请输入" << G.vexnum << "个顶点" << endl; G.vexs = (char *) malloc((G.vexnum+1) * sizeof(char)); //需要开辟多一个空间存储'\0' //构造顶点向量 for(int i = 0; i < G.vexnum; i++) { cout << "请输入第" << i+1 << "个顶点:"; cin >> G.vexs[i]; } G.vexs[G.vexnum] = '\0';

图的深度优先遍历和广度优先遍历

华北水利水电学院数据结构实验报告 20 10 ~20 11 学年第一学期2008级计算机专业 班级:107学号:200810702姓名:王文波 实验四图的应用 一、实验目的: 1.掌握图的存储结构及其构造方法 2.掌握图的两种遍历算法及其执行过程 二、实验内容: 以邻接矩阵或邻接表为存储结构,以用户指定的顶点为起始点,实现无向连通图的深度优先及广度优先搜索遍历,并输出遍历的结点序列。 提示:首先,根据用户输入的顶点总数和边数,构造无向图,然后以用户输入的顶点为起始点,进行深度优先和广度优先遍历,并输出遍历的结果。 三、实验要求: 1.各班学号为单号的同学采用邻接矩阵实现,学号为双号的同学采用邻接表实现。 2.C/ C++完成算法设计和程序设计并上机调试通过。 3.撰写实验报告,提供实验结果和数据。 4.写出算法设计小结和心得。 四、程序源代码: #include #define MaxVerNum 50 struct edgenode { int endver; int inform; edgenode* edgenext; }; struct vexnode { char vertex; edgenode* edgelink; }; struct Graph { vexnode adjlists[MaxVerNum]; int vexnum; int arcnum; }; //队列的定义及相关函数的实现 struct QueueNode

{ 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 或∈E; A[i,j]={ 0,反之 图5-2中有向图G1和无向图G2的邻接矩阵分别为M1和M2: M1=┌0 1 0 1 ┐ │ 1 0 1 0 │ │ 1 0 0 1 │ └0 0 0 0 ┘ M2=┌0 1 1 1 ┐ │ 1 0 1 0 │ │ 1 1 0 1 │ └ 1 0 1 0 ┘ 注意无向图的邻接是一个对称矩阵,例如M2。 用邻接矩阵表示法来表示一个具有n个顶点的图时,除了用邻接矩阵中的n*n个元素存储顶点间相邻关系外,往往还需要另设一个向量存储n个顶点的信息。因此其类型定义如下: VertexType vertex[MAX_VERTEX_NUM]; // 顶点向量 AdjMatrix arcs; // 邻接矩阵 int vexnum, arcnum; // 图的当前顶点数和弧(边)数 GraphKind kind; // 图的种类标志

若图中每个顶点只含一个编号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, 若或(Vi,Vj) A[i,j]={ ∞, 否则。 其中Wij为或(Vi,Vj)上的权值。相应地,网的邻接矩阵表示的类型定义应作如下的修改:adj:weightype ; {weightype为权类型} 图5-6列出一个网和它的邻接矩阵。 ┌∞31∞∞┐ │∞∞51∞│ │∞∞∞∞∞│ │∞∞6∞∞│ └∞322∞┘ (a)网(b)邻接矩阵 图5-6 网及其邻接矩阵 对无向图或无向网络,由于其邻接矩阵是对称的,故可采用压缩存贮的方法,

采用非递归深度优先遍历算法

2007-05-27 晴 //采用非递归深度优先遍历算法,可以将回溯法表示为一个非递归过程 #include using namespace std; class Knap { friend int Knapsack(int p[],int w[],int c,int n ); //设置友元函数 public: void print() //定义类内函数打印结果 { for(int m=1;m<=n;m++) { cout<

}; 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 或∈E; A[i,j]={ 0,反之 图5-2中有向图G1的邻接矩阵为M1 M1=┌0 1 0 1 ┐ │ 1 0 1 0 │ │ 1 0 0 1 │ └0 0 0 0 ┘ 用邻接矩阵表示法来表示一个具有n个顶点的图时,除了用邻接矩阵中的n*n个元素存储顶点间相邻关系外,往往还需要另设一个向量存储n个顶点的信息。因此其类型定义如下: VertexType vertex[MAX_VERTEX_NUM]; // 顶点向量 AdjMatrix arcs; // 邻接矩阵 int vexnum, arcnum; // 图的当前顶点数和弧(边)数 GraphKind kind; // 图的种类标志 若图中每个顶点只含一个编号i(1≤i≤vnum),则只需一个二维数组表示图的邻接矩阵。此时存储结构可简单说明如下: type adjmatrix=array[1..vnum,1..vnum]of adj; 利用邻接矩阵很容易判定任意两个顶点之间是否有边(或弧)相联,并容易求得各个顶点的度。

对于有向图,顶点Vi的出度OD(Vi)为邻接矩阵第i行元素之和,顶点Vi 的入度ID(Vi)为第i列元素之和。即 n n OD(Vi)=∑A[i,j],OD(Vi)=∑A[j,i]) j=1j=1 用邻接矩阵也可以表示带权图,只要令 Wij, 若或(Vi,Vj) A[i,j]={ ∞, 否则。 其中Wij为或(Vi,Vj)上的权值。相应地,网的邻接矩阵表示的类型定义应作如下的修改:adj:weightype ; {weightype为权类型} 2、图的遍历: *深度优先搜索 深度优先搜索遍历类似于树的先根遍历,是树的先根遍历的推广。假设初始状态是图中所有的顶点未曾被访问,则深度优先遍历可从图的某个顶点V出发,访问此顶点,然后依次从V的未被访问的邻接点出发深度优先遍历图,直至图中所有和V有路径相通的顶点都被访问到;若此时图中尚有顶点未被访问,则另选图中的一个未被访问的顶点,重复上述过程,直至图中所有顶点都被访问到为止。 以图中无向图G 4为例,深度优先遍历图的过程如图所示。假设从顶点V 1 出 发进行搜索,在访问了顶点V 1后,选择邻接点V 2 。因为V 2 未曾访问,则从V 2 出 发进行搜索。依次类推,接着从V 4,V 8 ,V 5 出发进行搜索。在访问了V 5 之后,由于 V 5的邻接点已都被访问,则搜索回到V 8 。由于同样的理由,搜索继续回到V 4 ,V 2 直至V 1,此时由于V 1 的另一个邻接点为被访问,则搜索又从V 1 到V 3 ,再继续进 行下去。由此得到顶点的访问序列为: V 1 V 2 V 4 V 8 V 5 V 3 V 6 V 7

实验四-图的应用――深度优先/广度优先搜索遍历

数据结构实验报告 实验四图的应用 一、实验题目: 图的应用——xx优先/xx优先搜索遍历 二、实验内容: 很多涉及图上操作的算法都是以图的遍历操作为基础的。试编写一个算法,实现图的深度优先和广度优先搜索遍历操作。 要求: 以邻接矩阵或邻接表为存储结构,以用户指定的顶点为起始点,实现连通无向图的深度优先及广度优先搜索遍历,并输出遍历的结点序列。(注: 学号为奇数的同学使用邻接矩阵存储结构实现,学号为偶数的同学使用邻接矩阵实现) 提示: 首先,根据用户输入的顶点总数和边数,构造无向图,然后以用户输入的顶点为起始点,进行深度优先、广度优先搜索遍历,并输出遍历的结果。 三、程序源代码: #include #include #define MAX_VERTEX_NUM 20 #define OVERFLOW -1 int visited[80]; typedef struct ArcNode{

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为或{Vj,Vt},若ei为{Vj,Vt},称ei为以V j 和Vt为端点的无向边;若ei 为,称ei为以V j为起点,Vt为终点的有向边;W(G)称为E→VxV的关联函数。 2图的存储结构 图的存储结构除了要存储图中各个顶点的本身的信息外,同时还要存储顶点与顶点之间的所有关系(边的信息),因此,图的结构比较复杂,很难以数据元素在存储区中的物理位置来表示元素之间的关系,但也正是由于其任意的特性,故物理表示方法很多。常用的图的存储结构有邻接矩阵、邻接表、十字链表和邻接多重表。邻接表是图的一种链式存储结构。对图的每个顶点建立一个单链表(n 个顶点建立n个单链表),第i个单链表中的结点包含顶点Vi的所有邻接顶点。 图1 无向图G 该图的G的邻接表表示如下:

图深度优先搜索C++

#include using namespace std; #define NULL 0 #define MaxSize 20 struct edgenode //边表结点 { int adjvex; edgenode *next; }; struct vexnode //顶点表结点 { int vertex; edgenode *link; }; class ALGraph //邻接表类{ public: void CreatGraph(); //创建临界表 void D_Search(int i, int j); //深度优先搜索判断 void B_Search(int i, int j); //广度优先搜索判断 private: vexnode ga[MaxSize]; //顶点数组int n,e; //顶点数,边数 }; void ALGraph::CreatGraph() { edgenode *s; int i,start,end; cout<<"请输入顶点数和边数:"<>n>>e; while( e<(n-1) ) { cout<<"错误!该图不是连通图!请重新输入:"<>n>>e;

} cout<<"请输入顶点编号:"<>ga[i].vertex; ga[i].link=NULL; } cout<<"请依次输入各边相连的结点"<>start>>end; while( ( start<1 || start>n ) || ( end<1 || end >n ) ) { cout<<"输入有误,请重新输入"<>start>>end; } s=new edgenode; s->adjvex=end; s->next=ga[start-1].link; ga[start-1].link=s; } } //按深度优先搜索,判断v[i]和v[j]之间是否存在路径 void ALGraph::D_Search(int start ,int end) { cout<<"--------------------------------------------------"<adjvex-1; while(p!=NULL) { if(!visited[p->adjvex])

图的深度和广度遍历 - 实验报告

实验报告 一、实验目的和内容 1.实验目的 掌握图的邻接矩阵的存储结构;实现图的两种遍历:深度优先遍历和广度优先遍历。 2.实验内容 1.图的初始化; 2.图的遍历:深度优先遍历和广度优先遍历。 二、实验方案 程序主要代码: ///

///邻接矩阵的节点数据 /// public struct ArcCell { public int Type; //顶点的关系类型,对无权图,用1或0表示相邻; //对带权图,则为权值类型。 public object Data; //该弧相关信息 public ArcCell(int type,object data) { Type = type; Data = data; } } /// ///图的类型 /// public enum GKind {DG,DN,UDG,UDN}; //有向图,有向网,无向图,无向网

///

///图类 /// public class Graph { public static int Max_Vertex_Num = 20; //最大顶点数 private object [] Vexs; //顶点数据数组 private ArcCell [,] Arcs; //邻接矩阵 private GKind Kind; //图的种类 private int VexNum,ArcNum; //当前顶点数和弧数 /// ///图的初始化方法 /// ///顶点数 ///弧数 ///图的类型 public Graph(int vexnum,int arcnum,GKind k) { VexNum = vexnum; ArcNum = arcnum; Kind = k; Vexs = new object[Max_Vertex_Num]; Arcs = new ArcCell[Max_Vertex_Num,Max_Vertex_Num]; } /// ///设置v1,v2之间的弧的权值,顶点的关系类型,对无权图,用1或0表示相邻; ///对带权图,则为权值类型。 /// ///顶点1 ///顶点2 ///权 ///成功返回真,否则返回假 public bool SetArcInfo(int v1,int v2,int adj,object data) { if(v1

深度优先搜索算法DFS

深度优先搜索算法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;ivexnum;i++) { printf("请输入顶点名:\n"); scanf("%c",&G->vertices[i].data); scanf("%c",&G->vertices[i].data); G->vertices[i].firstarc=NULL; printf("请输入该点关联顶点数:\n"); scanf("%d",&n); if(n!=0) printf("请输入该弧所指向顶点位置:\n"); for(j=0;jadjver); if(G->vertices[i].firstarc==NULL) { G->vertices[i].firstarc=q; p=q; }

无向图的深度优先遍历序列

#include #define MAXVERTEXNUM 20 #define TRUE 1 #define FALSE 0 typedef char VertexType; typedef int VRType; typedef int Status; typedef int InfoType; typedef enum {DG,DN,UDG,UDN} GraphKind; typedef struct ArcCell { // 弧的定义 VRType adj; // VRType是顶点关系类型。 // 对无权图,用1或0表示相邻否; // 对带权图,则为权值类型。 InfoType *info; } ArcCell,AdjMatrix[MAXVERTEXNUM][MAXVERTEXNUM]; typedef struct { // 图的定义 VertexType vexs[MAXVERTEXNUM]; // 顶点信息 AdjMatrix arcs; // 弧的信息 int vexnum, arcnum; // 顶点数,弧数 GraphKind kind; // 图的种类标志 } MGraph; int visited[MAXVERTEXNUM]; int LocateVex(MGraph G, VertexType v){ int i; for(i=0; i

相关文档
最新文档