首先要理解树与图
树是一种特殊的图,是无环连通图
图分为两种图
有向图和无向图
无向图是一种特殊的有向图
图的遍历主要就是是深度优先遍历和宽度优先遍历,都是基于dfs和bfs思想形成的,核心代码和主要思想也都相似。
一.深度优先遍历
就像是dfs,先选择一条路走到头,再回溯到支点走另一条路,直至终点。
void dfs(int x)
{
vis[x] = 1;//记录x被访问过
for (int i = head[x]; i; i = nxt[i])
{
int y = ver[i];//边的终点
if (vis[y]) continue;//如果访问过,则跳转到下一个
dfs(y);//递归遍历
}
}
关于深度优先遍历的应用,可以求树的重心
将一个节点在树中删除,就会分成若干个无联系的部分,每个部分都是一颗子树,对于每颗子树,我们取最大值存入max,再对max中的值求最小值,得到的就是重心。
int dfs(int u)
{
st[u]=true;//标记被搜过的点
itn sun=1,res=0;
for(int i=h[u];i!=-1;i=ne[i])
{
int j=e[i];
if(!st[j])
{
int s=dfs(j);
res=max(res,s);
sum+=s;
}
}
res=max(res,n-sum);
ans=min(ans,res);
return sum;
}
二.广度优先遍历
也就像是bfs,一层一层地向下遍历。
先将第一个点存入队列,不断地将队头拿出,将队头能达到的点存入队列直至结束
int hh=0;tt=0;
q[0]=1;//0号节点是编号为一的节点
memset(d,-1,sizeof d);
d[1]=0;//判断是否经过 并存储距离
while(hh<=tt)//当队列不为空
{
int t=q[hh++];//取出队头并弹出
for(inr i=h[t];i!=-1;i=ne[i])//遍历每个邻边
{
int j=e[i];
if([d[j]==-1)//若没有被拓展
{
d[j]=d[t]+1;//距离
q[++tt]=j; //将j节点入队
}
}
}