数据结构实验报告三实现深度优先搜索与广度优先搜索算法.docx
- 文档编号:8110417
- 上传时间:2023-01-28
- 格式:DOCX
- 页数:16
- 大小:54.91KB
数据结构实验报告三实现深度优先搜索与广度优先搜索算法.docx
《数据结构实验报告三实现深度优先搜索与广度优先搜索算法.docx》由会员分享,可在线阅读,更多相关《数据结构实验报告三实现深度优先搜索与广度优先搜索算法.docx(16页珍藏版)》请在冰豆网上搜索。
数据结构实验报告三实现深度优先搜索与广度优先搜索算法
佛山科学技术学院
实验报告
课程名称数据结构
实验项目实现深度优先搜索与广度优先搜索算法
专业班级10网络工程2姓名张珂卿学号2010394212
指导教师成绩日期2011年11月16日
一、实验目的
1、通过本实验,掌握图,无向图的基本概念,掌握图的遍历;
2、掌握图的深度优先搜索(DFS)与广度优先搜索(BFS)算法。
二、实验内容
1、建立图的存储方式;
2、图的深度优先搜索算法;
3、图的广度优先搜索算法。
三、实验原理
图的遍历是图的算法中一种非常重要的算法,通过建立图的存储结构,采用深度优先搜索与广度优先搜索算法可以进行图的遍历;
深度优先遍历是树的先根遍历的推广,是将某一条枝上的所有节点都搜索到了之后,才转向搜索另一条枝上的所有节点;
广度优先遍历与深度优先遍历的区别在于:
广度优先遍历是以层为顺序,将某一层上的所有节点都搜索到了之后才向下一层搜索。
四、实验步骤
1.建立图的存储结构;
2.输入图的基本接点与信息,初始化图;
3.编写图的深度优先搜索(DFS)和广度优先搜索算法(BFS)程序;
4.采用菜单形式进行显示与选择。
5.测试数据和结果显示
(1)从键盘输入顶点数和边数;
(2)输入顶点信息;
(3)输入边的信息,以(a,b)的形式输入边的信息,构建一个无向图;
(4)对此无向图进行深度优先搜索和广度优先搜索,并输出正确的序列。
五、程序源代码及注释
/*******************************
*采用邻接表的存储结构
*构建无向图
*图的创建过程中暂不支持重复验证,
因此不能对一条边进行重复定义
******************************/
#include
#include
#include
#defineMAX_VERTEX_NUM20
typedefstructArcNode{
intadjvex;
structArcNode*nextarc;
//InfoType*info;
}ArcNode;
/*********************************
*链表结点的结构用于创建栈或是队列
********************************/
typedefstructLinkNode{
ArcNode*parc;//存储指针地址
structLinkNode*next;//指向一下个结点
}LinkNode;
typedefstructVNode{
charcData;//顶点元素值
ArcNode*firstarc;//指向第一条依附于该点的边
}VNode,AdjList[MAX_VERTEX_NUM];
typedefstruct{
AdjListvertices;
intvexnum;//图的当前顶点数和弧数
intarcnum;
}ALGraph;
intVisited[MAX_VERTEX_NUM];
/*********************************
*将生成的图打印出来以便确认正确性
********************************/
intPrintCheck(ALGraph*pag)
{
inti;
ArcNode*p;
printf("\nChecktheGraph!
\n");
printf("No\tdata\tnext\tnext\t.....\n");
for(i=0;i
{
printf("%d\t%c\t",i,pag->vertices[i].cData);
p=pag->vertices[i].firstarc;
while(p)
{
printf("%d\t",p->adjvex);
p=p->nextarc;
}
printf("\n");
}
return1;
}
/**************************
*采用前插法创建邻接表
*************************/
intCreateGraph(ALGraph*pag,intstart,intend)
{
ArcNode*arcNodes=(ArcNode*)malloc(sizeof(ArcNode));
ArcNode*arcNodee=(ArcNode*)malloc(sizeof(ArcNode));
ArcNode*p;
if(!
arcNodes||!
arcNodee)return0;
//从start->end生成关系
arcNodes->adjvex=end;//下一结点的位置
p=pag->vertices[start].firstarc;
if(!
p)//第一个结点单独构造
{
arcNodes->nextarc=pag->vertices[start].firstarc;
pag->vertices[start].firstarc=arcNodes;
}
else{
while(p->nextarc)p=p->nextarc;
p->nextarc=arcNodes;
arcNodes->nextarc=NULL;
}
//end->start的关系生成
arcNodee->adjvex=start;//下一结点的位置
p=pag->vertices[end].firstarc;
if(!
p)//第一个结点单独构造
{
arcNodee->nextarc=pag->vertices[end].firstarc;
pag->vertices[end].firstarc=arcNodee;
}
else{
while(p->nextarc)p=p->nextarc;
p->nextarc=arcNodee;
arcNodee->nextarc=NULL;
}
return1;
}
/****************************************
*深度优先遍历,非递归方式
*结点先访问再入栈
*栈的存储结构直接采用了LinkNode构成的链表
*采用前插法进行插入与删除,从而也可以完成栈的功能
*栈空条件Stack->next==NULL
***************************************/
voidDFSTraverse(ALGraphag,intstart)
{
LinkNode*Stack=(LinkNode*)malloc(sizeof(LinkNode));//链表头结点,用做栈
LinkNode*pStack=(LinkNode*)malloc(sizeof(LinkNode));//对栈操作的指针
LinkNode*temp;//临时存储
ArcNode*p;
inti;
if(!
pStack||!
Stack)return;
Stack->next=NULL;
p=ag.vertices[start].firstarc;
Visited[start]=1;//Flag
printf("\n输出深度优先遍历顺序:
");
printf("%c",ag.vertices[start].cData);//访问第一个点
while
(1)//正常情况下执行一次,为了打印孤立结点
{
//pushstack
pStack->parc=p;
pStack->next=Stack->next;//将p接入链式栈中
Stack->next=pStack;
//pushover
while(p&&(Stack->next))//当并且栈不为空时
{
while(p)
{
if(Visited[p->adjvex])p=p->nextarc;
else
{
Visited[p->adjvex]=1;
printf("%c",ag.vertices[p->adjvex].cData);//VisitFunction
//pushstack
pStack=(LinkNode*)malloc(sizeof(LinkNode));
if(!
pStack)return;//结点建立不成功
pStack->parc=p;
pStack->next=Stack->next;
Stack->next=pStack;
//pushover
p=ag.vertices[p->adjvex].firstarc;
}
}
//popstack
temp=Stack->next;
Stack->next=temp->next;
p=temp->parc->nextarc;
free(temp);
//popover
}
for(i=0;i { if(! Visited[i])printf("%c",ag.vertices[i].cData); p=ag.vertices[i].firstarc; } if(i=ag.vexnum)break; } printf("\n\n"); }; /**************************************** *广度优先遍历,非递归方式 *队列的存储结构直接采用了LinkNode构成的链表 *采用后接法进行插入,并用前插法进行删除 *从而完成队列的功能,队空条件Queue->next==NULL ***************************************/ voidBFSTraverse(ALGraphag,intstart) { LinkNode*Queue=(LinkNode*)malloc(sizeof(LinkNode));//链表头结点,用做队列 LinkNode*pQueue=(LinkNode*)malloc(sizeof(LinkNode));//对队列操作的指针 LinkNode*temp;//临时存储 LinkNode*last;//指向最后一个元素的指针 ArcNode*p; inti; if(! Queue||! pQueue)return; printf("\n输出广度优先遍历次序: "); printf("%c",ag.vertices[start].cData); p=ag.vertices[start].firstarc; Visited[start]=1; while (1)//正常情况下执行一次循环 { //EnQueue pQueue->parc=p; Queue->next=pQueue; pQueue->next=NULL; last=pQueue;//指向最后一个元素的指针 //EnQueueover while(p&&Queue->next) { while(p) { if(! Visited[p->adjvex]) { Visited[p->adjvex]=1; printf("%c",ag.vertices[p->adjvex].cData);//VisitFunction //EnQueue pQueue=(LinkNode*)malloc(sizeof(LinkNode)); if(! pQueue)return; pQueue->parc=p; pQueue->next=NULL; last->next=pQueue; last=last->next;//指向最后一个元素的指针 //EnQueueover } p=p->nextarc; } //DeQueue temp=Queue->next; p=ag.vertices[temp->parc->adjvex].firstarc; Queue->next=temp->next; //DeQueueover } for(i=0;i { if(! Visited[i])printf("%c",ag.vertices[i].cData); p=ag.vertices[i].firstarc; } if(i=ag.vexnum)break; } printf("\n\n"); } /****************************************** *主函数负责对图的初始化工作 *其中包括图的结点初始化,边初始化 *其中大部分的while (1)语句 用于验证输入数据的有效性 ******************************************/ voidmain() { ALGraphag; inti,n,m; intchoose;//选择遍历结点 intstart,end;//边的起点与终点的位置 printf("说明: 采用邻接表的存储结构,生成无向图\n输入数据请回车确认\n\n"); while (1)//结点个数有效性验证 { printf("请输入图的结点个数,并回车: "); scanf("%d",&n); if(n elseprintf("\n请注意结点个数不能大于20,并且不能为0! \n"); } ag.vexnum=n; printf("\n初始化图的结点,输入字符并回车: \n"); for(i=0;i { printf("No.%d=",i); fflush(stdin); scanf("%c",&ag.vertices[i].cData); ag.vertices[i].firstarc=NULL; } m=(n-2)*(n+1)/2+1;//顶点数为n的图最多的边的数量为m while (1)//边的数量有效性验证 { printf("请输入边的数量: "); fflush(stdin); scanf("%d",&i); if(i<=m&&i>=0)break; elseprintf("\n请注意边的数量不能大于%d,并且不能小于1! \n",m); } ag.arcnum=i; printf("\n初始化图的边,结点从0开始计,最大为%d\n",n-1); for(i=1;i<=ag.arcnum;i++) { while (1)//起点有效性验证 { printf("第<%d>条边的起点: ",i); fflush(stdin); scanf("%d",&start); if(start elseprintf("重新输入"); } while (1)//终点有效性验证 { printf("第<%d>条边的终点: ",i); fflush(stdin); scanf("%d",&end); if(end =start)break; elseprintf("重新输入"); } printf("\n"); CreateGraph(&ag,start,end); } PrintCheck(&ag);//打印出生成的图 printf("\n开始进行图的遍历! \n"); while (1)//起始点有效性验证 { printf("请输入深度优先遍历的开始结点: "); fflush(stdin); scanf("%d",&choose); if(choose>=0&&choose elseprintf("重新输入"); } DFSTraverse(ag,choose);//深度优先遍历 i=0;//重新初始化Visited数组 while(Visited[i]! ='\0') { Visited[i]=0; i++; } while (1)//起始点有效性验证 { printf("请输入广度优先遍历的开始结点: "); fflush(stdin); scanf("%d",&choose); if(choose>=0&&choose elseprintf("重新输入"); } BFSTraverse(ag,choose);//广度优先遍历 system("pause"); } 程序运行截图 六、实验体会 这堂实现深度优先搜索与广度优先搜索算法的数据结构实验课难度明显比第二节课要大许多,刚开始有些丈二摸不着头脑,浪费了不少课上的时间,后来回去才慢慢深入,一点点了解了这堂课的内容,经历过不少错误之后,终于算是掌握了图,无向图的基本概念,掌握图的遍历,还有图的深度优先搜索(DFS)与广度优先搜索(BFS)算法。 到现在才真正明白原来专业课都不是很好学的,难度也是相当的大,但是相信这些都难不倒我,从这次数据结构实验课我又学到了不少专业知识,熟悉了实现深度优先搜索与广度优先搜索算法等各种算法。
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 数据结构 实验 报告 实现 深度 优先 搜索 广度 算法