图与DFS
1.1简析
图描述的是一些个体间的关系,与二叉树不同的是,不仅是祖先后代的层次关系,而是复杂的网状关系
1.2DFS
1.2.1DFS简析
a:从一个图的顶点点开始,对与该点有关联的点进行搜索
b:对遍历到的每个点重复a->b的操作
c:直到无点可遍历,再从没遍历过的点进行a操作。
d:所有点都遍历完毕。
简而言之,就是从一个点开始,按一条路径不断向下搜索,如果走到头,返回上一层,继续搜索未遍历到的点,以此不断循环往复直到全部遍历或者得到结果。
1.2.2DFS模板
void dfs(a1,a2,a3)
{
if(走到尽头||找到答案)
return ;
if(满足搜索条件||未访问过)
dfs(x1,x2,x3);
return ;//回溯
}
1.2.3DFS求连通块
输入一个m行n列的字符矩阵,统计字符@组成多少8连块,如果两个字符的格子相邻(上下左右对角线),就说他们同属一个8连块。求有多少8连块。<<紫书油田>>
分析:可以使用DFS遍历图,每次遍历对应一个连通分量编号用来描述格子的连通,所以每次遍历就是一个8连块。建立index二维数组,描述每个格子的连通分量,和判断是否遍历过。
代码如下:
//改自紫书代码
#include<iostream>
#include<cstring>
using namespace std;
const int maxn = 105;
char pic[maxn][maxn];
int m,n,index[maxn][maxn];
void dfs(int r, int c ,int id)
{
if(r < 0 || r >= m || c < 0 || c >= n) return;//越界退出
if(index[r][c] > 0 || pic[r][c] != '@') return;//不符合搜索条件退出
index[r][c] = id;
//遍历周边八个格子
for(int i = -1; i <= 1; i++)
for(int j = -1; j <= 1 ;j++)
if(i != 0 || j != 0) dfs(r + i, c + j, id);
}
int main()
{
cin>> m >>n;
for(int i = 0;i < m ; i++)
for(int j = 0;j < n;j++)
cin>>pic[i][j];
//把每个格子对应的编号置0
memset(index,0,sizeof(index));
int cnt = 0;
//遍历图,每次遍历更新连通编号(即一个8连块的编号)
//编号为0而且为@的格子能进入dfs
for(int i = 0; i < m ;i++)
for(int j = 0; j < n;j++)
if(index[i][j] == 0 && pic[i][j] == '@') dfs(i,j,++cnt);
cout<<cnt<<endl;
}
1.24树的dfs遍历
typedef struct node{
int val;
struct node * left;
struct node * rigtht;
}
//前序遍历
void tree_visit(Node * root)
{
if( root == NULL)
return ;
visit(root);
tree_visit(root->left);
tree_visit(root->right);
}
//中序遍历
void tree_visit(Node * root)
{
if( root == NULL)
return ;
tree_visit(root->left);
visit(root);
tree_visit(root->right);
}
//后续遍历
void tree_visit(Node * root)
{
if( root == NULL)
return ;
tree_visit(root->left);
tree_visit(root->right);
visit(root);
}