您当前的位置: 首页 > 技术文章 > 编程语言

深度优先搜索(DFS)和广度优先搜索(BFS)

作者: 时间:2023-06-11阅读数:人阅读

目录

深度优先

算法简介

图解

 算法实现

 广度优先

算法简介

 图解

 算法实现

深度优先和广度优先是在图和树的遍历搜索中比较常用的搜索方法

深度优先搜索(DFS)和广度优先搜索(BFS)(图1)

深度优先

算法简介

DFS是可用于遍历树或者图的搜索算法,DFS与回溯法类似,一条路径走到底后需要返回上一步,搜索第二条路径。在树的遍历中,首先一直访问到最深的节点,然后回溯到它的父节点,遍历另一条路径,直到遍历完所有节点。图也类似,如果某个节点的邻居节点都已遍历,回溯到上一个节点。

深度优先搜索是图论中的经典算法,利用深度优先搜索算法可以产生目标图的相应拓扑排序表,利用拓扑排序表可以方便的解决很多相关的图论问题,如最大路径问题等等。一般用栈数据结构来辅助实现DFS算法。根据深度优先搜索的特点,采用递归函数实现比较简单。但也可以不采用递归

图解

深度优先搜索(DFS)和广度优先搜索(BFS)(图2)深度优先搜索(DFS)和广度优先搜索(BFS)(图3)深度优先搜索(DFS)和广度优先搜索(BFS)(图4)

 深度优先搜索(DFS)和广度优先搜索(BFS)(图5)深度优先搜索(DFS)和广度优先搜索(BFS)(图6)深度优先搜索(DFS)和广度优先搜索(BFS)(图7)

 深度优先搜索(DFS)和广度优先搜索(BFS)(图8)深度优先搜索(DFS)和广度优先搜索(BFS)(图9)

 深度优先搜索(DFS)和广度优先搜索(BFS)(图10)

 算法实现

对于矩阵图的深度优先遍历

 深度优先搜索(DFS)和广度优先搜索(BFS)(图11)

int dxy[4][2]={//模拟上下左右四个方向
	-1,0,//向上(x减一,y不变)
	1, 0,//向下
	0,-1,//向左
	0, 1//向右
	}
void dfs(int x0,int y0)
{
	if(x0,y0满足某种条件)//找到目标点
	{
		//执行操作如输出路径等
		return;
	}
	for(int i=0;i<4;i++)//遍历四个方向每一个分支,对每一个分支都进行深度搜索
	{
		int dx=dxy[i][0];//移动后的横坐标
		int dy=dxy[i][1];//移动后的纵坐标
		if(坐标越界||遇到障碍物||...)//不满足条件
			continue;
		//执行操作
		dfs(dx,dy)//深度遍历
		//遍历结束恢复操作
	}
}

 广度优先

算法简介

 广度搜索,顾名思义,就是更大范围内搜索,先访问完当前顶点的所有邻接点,然后再访问下一层的所有节点,该算法适用于解决最短、最小路径等问题,但是构建广度优先算法需要维护自己的队列。

广度搜索是同时搜索所有路径,相当于一层一层地搜索,就好比波浪的扩展一样。此搜索方法跟树的层次遍历类似,因此宽度搜索一般都用队列存储结构。

比如二叉树的层次遍历,我们大概会有如下几个步骤:

  • 向Queue中放入root节点。
  • 只要这个Queue中有元素就一直遍历。
  • 每次遍历时,首先计算一下当前Queue里有多少个元素,这就是这棵树当前层级元素的数量,记作Size。
  • 接下来从Queue中移除Size中的多个元素,对他们进行符合我们题目的一些操作。
  • 移除每个节点时,把它们的子节点添加进Queue中。
  • 只要Queue中还有元素,说明还有下一个层级,就一直重复步骤3去处理下一个层级。

 图解

深度优先搜索(DFS)和广度优先搜索(BFS)(图12)深度优先搜索(DFS)和广度优先搜索(BFS)(图13)深度优先搜索(DFS)和广度优先搜索(BFS)(图14)深度优先搜索(DFS)和广度优先搜索(BFS)(图15) 深度优先搜索(DFS)和广度优先搜索(BFS)(图16)

 算法实现

static const int dirs[4][2]={{-1,0},{1,0},{0,-1},{0,1}};
void bfs(int row, int col) {
    if (row,col满足某种条件) {
        return;
    }
    int * queue = (int *)malloc(sizeof(int) * m * n);
    int head = 0;
    int tail = 0; 双指针实现队列先进先出
    queue[tail++] = row * n + col; 
    while (head != tail) {
        int row = queue[head] / n;
        int col = queue[head] % n;
        head++;
        for (int i = 0; i < 4; i++) {
            int newRow = row + dirs[i][0], newCol = col + dirs[i][1];
            if 满足某种条件(newRow >= 0 && newRow < m && newCol >= 0 && newCol < n &&……) {
                对点进行某种操作操作
                queue[tail++] = newRow * n + newCol;
            }
        }
    }
    free(queue);
}

本站所有文章、数据、图片均来自互联网,一切版权均归源网站或源作者所有。

如果侵犯了你的权益请来信告知我们删除。邮箱:licqi@yunshuaiweb.com

加载中~