【开卷数据结构 】图的遍历,广搜和深搜(基础)

简介: 【开卷数据结构 】图的遍历,广搜和深搜(基础)

图的遍历


Q:什么是图的遍历


A:图的遍历是指从图的某一顶点出发,按照某种搜索方式沿着图中的边对图中的所有结点访问一次且仅访问一次。


因为图的任一顶点都可能和其余的顶点相邻接,所以在访问某个顶点后,可能沿着某条路径搜索又回到该项点上。为避免同一顶点被访问多次,在遍历图的过程中,必须记下每个已访问过的顶点,为此可以设一个辅助数组 visited[] 来标记顶点是否被访问过。图的遍历算法主要有两种:广度优先搜索和深度优先搜索。


广度优先搜索


Q:什么是广度优先搜索


A:广度优先搜索(BFS)类似于二叉树的层序遍历算法。其基本思想是基本思想是:首先访问起始顶点 v,接着由 v 出发,依次访问 v 的各个未访问过的邻接顶 w1,w2,…… wi,然后依次访问 w1,w2,…… wi,的所有未被访问过的邻接顶点。 再从这些访问过的顶点出发,访问它们所有未被访问过的邻接顶点,直至图中所有顶点都被访问过为止。


若此时图中尚有顶点未被访问,则另选图中一个未曾被访问的顶点作为始点,重复上述过程,直至图中所有顶点都被访问到为止。


广度优先搜索是一种分层的查找过程,每向前走一步可能访问一此顶点,没有往回退的情况,因此它不是一个递归的算法。为了实现逐层的访问,算法必须借助一个辅助队列,以记忆正在访问的顶点的下一层顶点。


6856d3d65e9fe56803a88e6a53984098_96e0d4ec77364d77a4ee5ea02998c380.png


我们对这张图进行广度优先搜索。假设从 a 结点开始访问,a 先入队。此时队列非空,取出队头元素 a,由于 b,c 与 a 邻接且未被访问过,于是依次访问 b,c,并将 b,c依次入队。队列非空,取出队头元素 b,依次访问与 b 邻接且未被访问的顶点 d,e,并将 d,e 入队(注意:a与b也邻接,但 a 已置访问标记,故不再重复访问)。此时队列非空,取出队头元素 c,访问与 c 邻接且未被访问的顶点 f,g,并将 f,g 入队。此时,取出队头元素 d,但与 d 邻接且未被访问的顶点为空,故不进行任何操作。继续取出队头元素 e,将 h 入队列……最终取出队头元素 h 后,队列为空,从而循环自动跳出。遍历结果为 abcdefgh。


代码演示


bool visited[MAX_VERTEX_NUM];   //访问标记数组
void BFSTraverse(Graph G){    //对图G进行广度优先遍历
  for(i=0;i<G.vexnum;++i)
  visited[i]=FALSE;    //访问标记数组初始化
  InitQueue(Q);      //初始化辅助队列Q
  for(i=0;i<G.vexnum;++i)    //从0号顶点开始遍历
  if(!visited[i])     //对每个连通分量调用一次BFS
    BFS(G,i) ;      //v;未访问过,从 v:开始BFS?
)
void BFS(Graph G, int v){    //从顶点v出发,广度优先遍历图G
  visit(v);       //访问初始顶点v
  visited[v]=TRUE;      //对v做已访问标记
  Enqueue(Q,v);      //顶点v入队列Q
  while(!isEmpty(Q)){
  DeQueue(Q,v);     //顶点v出队列
  for(w=FirstNeighbor(G,v);w>=0;w=NextNeighbor(G,v))
  {        //检测v所有邻接点     
    if(!visited[w]){    //w为v的尚未访问的邻接顶点
    visit(w);    //访问顶点w
    visited[w]=TRUE;  //对w做已访问标记
    EnQueue(Q,w);   //顶点w入队列    
    }
  }
}


深度优先搜索


Q:什么是深度优先搜索


A:深度优先搜索类似于树的先序遍历。如其名称中所暗含的意思一样,这种搜索算法所遵循的搜索策略是尽可能“深”地搜索一个图。它的基本思想如下:首先访问图中某一起始顶点 v,然后由 v 出发,访问与 v 邻接且未被访问的任一顶点  w1,再访问与 w1 邻接且未被访问的任一顶点…重复上述过程。当不能再继续向下访问时,依次退回到最近被访问的顶点,若它还有邻接顶点未被访问过,则从该点开始继续上述搜索过程,直至图中所有顶点均被访问过为止。


6856d3d65e9fe56803a88e6a53984098_96e0d4ec77364d77a4ee5ea02998c380.png


我们对这张图进行深度优先搜索。其深度优先遍历的结果为:abdehcfg


代码演示


bool visited[MAX_VERTEX_NUM]; //访问标记数组
//从顶点出发,深度优先遍历图G
void DFS(Graph G, int v){
  int w;
  visit(v); //访问顶点
  visited[v] = TRUE;  //设已访问标记
  //FirstNeighbor(G,v):求图G中顶点v的第一个邻接点,若有则返回顶点号,否则返回-1。
  //NextNeighbor(G,v,w):假设图G中顶点w是顶点v的一个邻接点,返回除w外顶点v
  for(w = FirstNeighbor(G, v); w>=0; w=NextNeighor(G, v, w)){
    if(!visited[w]){  //w为u的尚未访问的邻接顶点
      DFS(G, w);
    }
  }
}
//对图进行深度优先遍历
void DFSTraverse(MGraph G){
  int v; 
  for(v=0; v<G.vexnum; ++v){
    visited[v] = FALSE; //初始化已访问标记数据
  }
  for(v=0; v<G.vexnum; ++v){  //从v=0开始遍历
    if(!visited[v]){
      DFS(G, v);
    }
  }
}

相关文章
|
1月前
|
存储 编译器 C++
【初阶数据结构】掌握二叉树遍历技巧与信息求解:深入解析四种遍历方法及树的结构与统计分析
【初阶数据结构】掌握二叉树遍历技巧与信息求解:深入解析四种遍历方法及树的结构与统计分析
|
6月前
【数据结构】二叉树(遍历,递归)
【数据结构】二叉树(遍历,递归
37 2
|
1月前
|
存储 算法
数据结构与算法学习十六:树的知识、二叉树、二叉树的遍历(前序、中序、后序、层次)、二叉树的查找(前序、中序、后序、层次)、二叉树的删除
这篇文章主要介绍了树和二叉树的基础知识,包括树的存储方式、二叉树的定义、遍历方法(前序、中序、后序、层次遍历),以及二叉树的查找和删除操作。
25 0
|
2月前
|
存储 算法 C语言
数据结构基础详解(C语言): 二叉树的遍历_线索二叉树_树的存储结构_树与森林详解
本文从二叉树遍历入手,详细介绍了先序、中序和后序遍历方法,并探讨了如何构建二叉树及线索二叉树的概念。接着,文章讲解了树和森林的存储结构,特别是如何将树与森林转换为二叉树形式,以便利用二叉树的遍历方法。最后,讨论了树和森林的遍历算法,包括先根、后根和层次遍历。通过这些内容,读者可以全面了解二叉树及其相关概念。
|
3月前
【数据结构】遍历二叉树(递归思想)-->赋源码
【数据结构】遍历二叉树(递归思想)-->赋源码
53 4
|
4月前
|
存储 算法 Python
“解锁Python高级数据结构新姿势:图的表示与遍历,让你的算法思维跃升新高度
【7月更文挑战第13天】Python中的图数据结构用于表示复杂关系,通过节点和边连接。常见的表示方法是邻接矩阵(适合稠密图)和邻接表(适合稀疏图)。图遍历包括DFS(深度优先搜索)和BFS(广度优先搜索):DFS深入探索分支,BFS逐层访问邻居。掌握这些技巧对优化算法和解决实际问题至关重要。**
44 1
|
6月前
|
机器学习/深度学习
数据结构——二叉树四种遍历的实现-1
数据结构——二叉树四种遍历的实现
数据结构——二叉树四种遍历的实现-1
|
5月前
|
存储 算法
数据结构和算法学习记录——二叉树的存储结构&二叉树的递归遍历(顺序存储结构、链表存储结构、先序中序后序递归遍历)
数据结构和算法学习记录——二叉树的存储结构&二叉树的递归遍历(顺序存储结构、链表存储结构、先序中序后序递归遍历)
63 0
数据结构和算法学习记录——二叉树的存储结构&二叉树的递归遍历(顺序存储结构、链表存储结构、先序中序后序递归遍历)
|
5月前
|
编译器 数据库 索引
数据结构篇:树形数据结构的基本概念及其遍历方法
数据结构篇:树形数据结构的基本概念及其遍历方法
81 0
|
6月前
|
机器学习/深度学习 算法 分布式数据库
数据结构与算法⑭(第四章_下)二叉树的模拟实现和遍历代码(下)
数据结构与算法⑭(第四章_下)二叉树的模拟实现和遍历代码
42 1

热门文章

最新文章

下一篇
无影云桌面