【bfs与dfs】基础
2017-08-04 23:14
246 查看
bfs : 广度优先搜索,一层一层搜索. 属于一种盲目搜寻法,目的是系统地展开并检查图中的所有节点,以找寻结果。换句话说,它并不考虑结果的可能位置,彻底地搜索整张图,直到找到结果为止。广度优先的基本思想是,从顶点v0出发,访问与v0相邻的点,访问结束后,再从这些点出发,继续访问,直到访问结束为止。标记被访问过的点同深搜一下,不过,广度优先一般需要用到队列。
dfs : 深度优先搜索。深度优先的基本思想简单说就是搜到底,重新搜。从v0为起点进行搜索,如果被访问过,则做一个标记,直到与v0想连通的点都被访问一遍,如果这时,仍然有点没被访问,可以从中选一个顶点,进行再一次的搜索,重复上述过程,所以深度优先的过程也是递归的过程。
DFS 和 BFS使用哪种跟具体的数据(源点和目标的位置)有关,比如你数据结构是树,要搜索根节点到某一叶子节点的路径。这时候,如果这个叶子节点距离根节点比较远,使用深度优先DFS效率最高。如果这个叶子节点距离根节点比较近,使用广度优先BFS效率更高。你可以自己画一个树,自己用脑子模拟一下这两个算法,一下子就明白了。
找到了两篇有图解的可以去看一看:bfs:http://blog.csdn.net/raphealguo/article/details/7523411
dfs:http://rapheal.iteye.com/blog/1526863
以下是两种的代码,也附有注释,:
广搜dfs:
深搜dfs:
dfs : 深度优先搜索。深度优先的基本思想简单说就是搜到底,重新搜。从v0为起点进行搜索,如果被访问过,则做一个标记,直到与v0想连通的点都被访问一遍,如果这时,仍然有点没被访问,可以从中选一个顶点,进行再一次的搜索,重复上述过程,所以深度优先的过程也是递归的过程。
DFS 和 BFS使用哪种跟具体的数据(源点和目标的位置)有关,比如你数据结构是树,要搜索根节点到某一叶子节点的路径。这时候,如果这个叶子节点距离根节点比较远,使用深度优先DFS效率最高。如果这个叶子节点距离根节点比较近,使用广度优先BFS效率更高。你可以自己画一个树,自己用脑子模拟一下这两个算法,一下子就明白了。
找到了两篇有图解的可以去看一看:bfs:http://blog.csdn.net/raphealguo/article/details/7523411
dfs:http://rapheal.iteye.com/blog/1526863
以下是两种的代码,也附有注释,:
广搜dfs:
#include <stdio.h> #include <string.h> #include <math.h> #include <stack> #include <queue> #include <vector> #include <algorithm> #define mem(a,b) memset(a,b,sizeof(a)) using namespace std; int map[5][5];//地图 int go[4][2]= {{1,0},{-1,0},{0,-1},{0,1}};//四个方向 int pre[10000];//用来寻找父亲节点 bool vis[10][10];//标记数组 struct node { int x,y,s; };//存储坐标信息及当前步数 int bfs(int x,int y) { node now,to;//先在的和将要走的 now.x=x,now.y=y,now.s=0; queue<node>q;//创建队列 vis[x][y]=1;//走过的标记为1 q.push(now);//加入队首 while(!q.empty()) { now=q.front(); if(now.x==4&&now.y==4) return now.s;//满足条件时返回走过的步数 q.pop(); for(int i=0; i<4; i++) { int xx=now.x+go[i][0]; int yy=now.y+go[i][1]; if(xx>=0&&yy>=0&&xx<5&&yy<5&&map[xx][yy]==0&&vis[xx][yy]==0)//判断是否越界 { vis[xx][yy]=1;//标记走过的 to.x=xx,to.y=yy,to.s=now.s+1; pre[xx*5+yy]=now.x*5+now.y;//存储坐标,转化成一维形式 q.push(to); } } } return 0; } void myprint(int n) { //printf("pre[%d]=(%d)\n",n,pre ); if(n==pre )return; myprint(pre );//寻找父亲节点 printf("(%d, %d)\n",n/5,n%5); }//回溯打印路径 int main() { mem(vis,0); for(int i=0; i<5; i++) for(int j=0; j<5; j++) scanf("%d",&map[i][j]);//读入地图 if(bfs(0,0)) { printf("(0, 0)\n");//先打印0 0 myprint(4*5+4);//从(4,4)开始回溯 } else printf("-1\n"); return 0; }
深搜dfs:
/* 深搜dfs */ #include <stdio.h> #include <string.h> #include <math.h> #include <stack> #include <queue> #include <vector> #include <algorithm> #define mem(a,b) memset(a,b,sizeof(a)) using namespace std; int map[10][10],min1; struct node { int x,y; };//存坐标 stack<node> s1;//用栈来存储路径 node ans[100];//存储反过来后路径 void mycopy(stack<node> a)//栈是反着来的,用这个倒过来 { for(int i=(int)a.size()-1; i>=0; i--) { ans[i]=a.top(); a.pop(); } } int go[4][2]= {{1,0},{-1,0},{0,1},{0,-1}};//四个方向 bool vis[10][10];//标记数组 void dfs(int x,int y,int step) { node now; now.x=x,now.y=y; s1.push(now);//把坐标存进栈中 if(x==4&&y==4)//当搜索到终点时 { if(step<min1) { min1=step;//更新最小的步数 mycopy(s1);//翻转栈中的路径 } } for(int i=0; i<4; i++) { int xx=x+go[i][0],yy=y+go[i][1]; if(xx>=0&&xx<5&&yy>=0&&yy<5&&map[xx][yy]==0&&vis[xx][yy]==0)//判断是否越界 { vis[xx][yy]=1;//走过的标记为1 dfs(xx,yy,step+1);//搜索下一层 vis[xx][yy]=0;//标记回来,以便下次搜索 } } s1.pop();//坐标出栈 } int main() { for(int i=0; i<5; i++) for(int j=0; j<5; j++) scanf("%d",&map[i][j]); mem(vis,0);//初始化标记数组 min1=999; while(s1.size()) s1.pop();//清空栈 dfs(0,0,0); if(min1==999) printf("-1\n"); else { //printf("%d\n",min1); for(int i=0; i<=min1; i++) printf("(%d, %d)\n",ans[i].x,ans[i].y);//输出结果 } return 0; }
相关文章推荐
- 数据结构基础(21) --DFS与BFS
- POJ 1985 Cow Marathon 求直径 DFS基础 和 BFS 基础
- 基础算法 之 BFS & DFS
- POJ 1979 基础搜索 DFS\BFS 一
- 图论基础(bfs+dfs简介)
- ACM基础算法复习(STL + DFS + BFS + 并查集 + 快速幂 + 欧几里得算法)
- 基础搜索——dfs,bfs(全排列与迷宫问题)
- HDU 1312 Red and Black(基础bfs或者dfs)
- 数据结构基础(21) --DFS与BFS
- HDOJ-1253 基础搜索问题总结[DFS()+BFS()]
- Clone Graph leetcode java(DFS and BFS 基础)
- HDU 1241 Oil Deposits (基础DFS 或者 BFS)
- 数据结构基础(五)图以及DFS、BFS
- PTA 2-1 列出连通集【DFS+BFS基础】
- Poj 3087 + Hdu 1312 + Hdu 1241 + Poj 3278 (基础BFS DFS)
- 算法基础-->图论(BFS,DFS)
- 数据结构基础 图的遍历(三) 之 BFS+DFS(非递归实现)
- BFS & DFS的基础学习
- 数据结构基础(21) --DFS与BFS
- 基础数据结构算法_DFS and BFS