湖南大学数据结构试验图遍历问题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
HUNAN UNIVERSITY
课程实习报告
题目:图的遍历问题
学生姓名刘乐
学生学号20080820208
专业班级通信工程2班
指导老师朱宁波
完成日期2010年5月17日
一、问题描述:
从图中某个顶点出发访问图中所有顶点,且使得每一顶点仅被访问一次,这个过程称为图的遍历。图的遍历是从图中某个顶点出发,沿着某条搜索路径对图中其余每个顶点进行访问, 并且使图中的每个顶点仅被访问一次的过程。
二、基本要求:
1、实现无向图的深度优先遍历和广度优先遍历。
2、分别输出每种遍历下的结点访问序列.从图中某个顶点出发,沿着某条搜索路径对图中每个顶点各做一次且仅做一次访问。它
是许多图的算法的基础。
三、实验主要模块构造思想:
深度优先搜索的过程
a 基本思想:
首先访问图中某一个指定的出发点Vi;
然后任选一个与顶点Vi相邻的未被访问过的顶点Vj;
以Vj为新的出发点继续进行深度优先搜索,直至图中所有顶点均被访问过。
b具体过程:
设x是当前被访问顶点,在对x做过访问标记后,选择一条从x出发的未检测过的边(x,y)。若发现顶点y已访问过,则重新选择另一条从x出发的未检测过的边,否则沿边(x,y)到达未曾访问过的y,对y访问并将其标记为已访问过;然后从y开始搜索,直到搜索完从y出发的所有路径,即访问完所有从y 出发可达的顶点之后,才回溯到顶点x,并且再选择一条从x出发的未检测过的边。上述过程直至从x出发的所有边都已检测过为止。此时,若x不是源点,则回溯到在x之前被访问过的顶点;否则图中所有和源点有路径相通的顶点(即从源点可达的所有顶点)都已被访问过,若图G是连通图,则遍历过程结束,否则继续选择一个尚未被访问的顶点作为新源点,进行新的搜索过程。
广度优先遍历(Breadth-First Traverse):
特点:尽可能先从指定的出发点,横向地访问图中各个顶点。
1.广度优先遍历的定义
在访问了起始点之后,首先依次访问起始点的各个邻接点,然后依次访问这些顶点中未被访问过的邻接点.依此类推,直到所有被访问到的顶点的邻接点都被访问过为止.
2. 广度优先搜索的过程
a算法基本思想:
首先访问图中某一指定的出发点Vi;
然后依次访问Vi的所有接点Vi1,Vi2…Vit;
再次访问Vi1,Vi2…,Vit的邻接点中未经访问过的顶点,依此类推,直到图中所有顶点均被访问为止。
b具体过程:
从广度优先搜索遍历方法可知,先被访问的顶点的邻接点也被访问,即假设顶点V在W之前被访问,那么顶点V的所有未经访问的邻接点也在顶点W的所有未经访问的邻接点之前被访问。这样可以在广度优先遍历的算法中设置一个队列结构,用以保存已访问过的顶点的序号,访问该顶点的所有未经访问的顶点。
广度优先搜索是一种分层的搜索过程,每向前走一步可能访问一批顶点,不像深度优先搜索那样会出现回退的现象。因此它不是个递归的过程。为了实现逐层访问,算法中使用了一个队列以记忆正在访问的这一层和上一层的顶点,以便于向下一层访问。为了避免重复访问,需要一个辅助函数visitvex[]给被
访问过的顶点加标记。
四、设计概要:
数据类型及函数定义
定义图
typedef struct{
int V[M];
int R[M][M];
int vexnum;
}Graph;
创建图
void creatgraph(Graph *g,int n) 打印图的邻接矩阵
void printgraph(Graph *g)
访问顶点
void visitvex(Graph *g,int vex) 深度递归遍历
void dfs(Graph *g,int vex) 队列的基本操作
定义队列
typedef struct{
int V[M];
int front;
int rear;
}Queue;
判断队列是否为空
quempty(Queue *q)
入队操作
enqueue(Queue *q,int e)
出队操作
dequeue(Queue *q)
广度遍历
void BESTraverse(Graph *g)
本程序包含四个模块:
主程序模块
void main ()
{
构造一个图;
打印图的邻接矩阵
进行深度优先遍历图;
进行广度优先遍历图;
};
五、算法分析设计:
算法一:
存在的问题:图中可能存在回路,且图的任一顶点都可能与其他顶点相通,在访问完某个顶点之后可能会沿着某些边又回到了曾经访问过的顶点
解决办法:
为了避免重复访问,可设置一个标志顶点是否被访问过的辅助标志visitvex 辅助数组visitvex 的初始状态为0,在图的遍历过程中,一旦此顶点被访问,就立刻让visitvex为1,防止它被多次访问
Visitevex[0..n-1]的设置:
图中任一顶点都可能和其它顶点相邻接。在访问了某顶点之后,又可能顺着某条回路又回到了该顶点。为了避免重复访问同一个顶点,必须记住每个已访问的顶点。为此,可设一布尔向量visitvex[0..n-1],其初值为假,一旦访问了顶点Vi之后,便将visitvex[i]置为真。
算法二:以邻接矩阵为存储结构的图的深度优先搜索遍历的算法
void dfs(Graph *g,int vex)
{
int w;
visited[vex]=1; 标记vex已被访问过
visitvex(g,vex); 访问图g的顶点
for(w=firstadjvex(g,vex);w>0;w=nextadjvex(g,vex,w))
if(!visited[w])
{
dfs(g,w);
}
}
从初始点vex出发广度优先搜索由邻接矩阵R表示的图
void dfstraverse(Graph *g)
{
int i;
for(i=1;i<=g->vexnum;i++)
visited[i]=0;
for(i=1;i<=g->vexnum;i++)
if(!visited[i])
{dfs(g,i);}
}
算法三:以邻接矩阵为存储结构的图的广度优先搜索遍历的算法
从初始点vex出发广度优先搜索由邻接矩阵R表示的图
void BESTraverse(Graph *g)
{
int i;
Queue *q=(Queue *)malloc(sizeof(Queue)); 定义一个队列q,其元素类型应为Queue型
for(i=1;i<=g->vexnum;i++)
{
visited[i]=0; 标记初始点i未被已访问过