图的遍历 (dfs与bfs)x

遍历是很多图论算法的基础,所谓图的遍历( graph traversal),也称为搜索( search),就是从图中某个顶点出发,沿着一些边访遍图中所有的顶点,且使每个顶点仅被访问一次。

        遍历可以采取两种方法进行:

        深度优先搜索( DFS depth first search

        广度优先搜索( BFS breadth first search)。

对图进行存储与遍历:

输入:

第一行:顶点数n

第二行:边数m

以下m行,每行两个顶点编号uv

1DFS 遍历

深度优先搜索是一个递归过程,有回退过程。

对一个无向连通图,在访问图中某一起始顶点u 后,由u 出发,访问它的某一邻接顶点v1;再从v1 出发,访问与v1 邻接但还没有访问过的顶点v2;然后再从v2 出发,进行类似的访问;;如此进行下去,直至到达所有邻接顶点都被访问过的某个顶点x 为止;接着,回退一步,回退到前一次刚访问过的顶点,看是否还有其它没有被访问过的邻接顶点,如果有,则访问此顶点,之后再从此顶点出发,进行与前述类似的访问;如果没有,就再回退一步进行类似的访问。

重复上述过程,直到该连通图中所有顶点都被访问过为止。

模板:

DFS( 顶点 u ) { //从顶点 i 进行深度优先搜索

    vis[ u ] = 1; //将顶点 i 的访问标志置为 1

    for( j=1; j<=n; j++ ) { //对其他所有顶点 j

//j i 的邻接顶点,且顶点 j 没有访问过

if( map[u][ j ]==1 && !vis[ j ] ){

//递归搜索前的准备工作需要在这里写代码

DFS( j ) //从顶点 j 出发进行 DFS 搜索

//以下是 DFS 的回退位置

//在很多应用中需要在这里写代码

}

    }

}

#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>

const int Maxn=1010;

using namespace std;

int m,n;
int g[Maxn][Maxn];
bool b[Maxn];

void dfs(int i)
{
    if(i<n-1) cout<<char(i+64)<<"-->";
    else cout<<char(i+64);//防止最后多输出一个箭头
    b[i]=1;
    for(int k=1;k<=n;k++)
    {
        if(g[i][k]==1&&!b[k])//如果k为是 i 的邻接顶点并且k没有被搜过
        {
            dfs(k);//继续搜索k
        }
    }
}

int main()
{
    char a,b;
    scanf("%d %d",&m,&n);
    for(int i=1;i<=n;i++)
    {
        cin>>a>>b;//需要用cin输入
        g[a-64][b-64]=g[b-64][a-64]=1;//进行标记
    }
    dfs(1);
    return 0;
} 

2BFS 遍历

广度优先搜索( BFS Breadth First Search)是一个分层的搜索过程,没有回退过程,是非递归的。

BFS 算法思想:

对一个连通图,在访问图中某一起始顶点u 后,由u 出发,依次访问u 的所有未访问过的邻接顶点v1, v2, v3, vt;然后再顺序访问v1, v2, v3, vt 的所有还未访问过的邻接顶点;再从这些访问过的顶点出发,再访问它们的所有还未访问过的邻接顶点,……,如此直到图中所有顶点都被访问到为止。

BFS 算法的实现:

      与深度优先搜索过程一样,为避免重复访问,也需要一个状态数组 visited[n],用来存储各顶点的访问状态。如果 visited[i] = 1,则表示顶点 i 已经访问过;如果 visited[i] = 0,则表示顶点i 还未访问过。初始时,各顶点的访问状态均为 0

      为了实现逐层访问, BFS 算法在实现时需要使用一个队列,来记忆正在访问的这一层和上一层的顶点,以便于向下一层访问(约定在队列中,取出元素的一端为队列头,插入元素的一端为队列尾,初始时,队列为空)

#include<iostream>
#include<cstring>
#include<string>
#include<cstdio>
const int Maxn=1010;

using namespace std;

int m,n;
int g[Maxn][Maxn],que[Maxn];
bool b[Maxn];

void bfs(int u)
{
    b[u]=1;//将第一个元素进行标记
    cout<<u;//并输出
    int head=0,tail=1;//制定队头与队尾
    que[1]=u;//将第一个元素进队列,作为头号元素
    while(head<tail)//当队头队尾重合之前
    {
        head++;//删除第一个元素,将head指针指向下一个
        for(int i=1;i<=n;i++)
        {
            if(g[que[head]][i]==1&&!b[i])//如果为此时搜索的邻接顶点并且为被标记
            {
                b[i]==1;
                que[++tail]=i;//入队
            }
        }
    }
}

int main()
{
    char a,b;
    scanf("%d %d",&m,&n);
    for(int i=1;i<=n;i++)
    {
        cin>>a>>b;
        g[a-64][b-64]=1;
    }
    bfs(1);
    for(int i=2;i<=n;i++)
    {
        cout<<"->"<<que[i];//输出队列
    }
    return 0;
} 
时间: 2024-08-02 15:11:19

图的遍历 (dfs与bfs)x的相关文章

图的遍历——DFS和BFS模板(一般的图)

关于图的遍历,通常有深度优先搜索(DFS)和广度优先搜索(BFS),本文结合一般的图结构(邻接矩阵和邻接表),给出两种遍历算法的模板 1.深度优先搜索(DFS) #include<iostream> #include<unordered_map> #include<queue> #include<cstring> #include<cstdlib> #include<cmath> #include<algorithm> #

图的遍历 DFS和BFS

深度优先搜索 (Depth First Search, DFS): void DFS ( Vertex V ) { visited[ V ] = true; for ( V 点 的每个邻接点 W ) if ( !visited[ W ] ) DFS( W ); } 若有N 个顶点.E 条边,时间复杂度是 用邻接表存储图,有O(N+E) 用邻接矩阵存储图,有O(N 2 ) 广度优先搜索 (Breadth First Search, BFS) void BFS ( Vertex V ) { visi

图的遍历(DFS、BFS)

理论: 深度优先搜索(Depth_Fisrst Search)遍历类似于树的先根遍历,是树的先根遍历的推广: 广度优先搜索(Breadth_First Search) 遍历类似于树的按层次遍历的过程: java实现 Vertex.java package 图; public class Vertex{ String value; boolean isVisited; Vertex(String value) { this.value=value; this.isVisited=false; }

785. 判断二分图——本质上就是图的遍历 dfs或者bfs

785. 判断二分图 给定一个无向图graph,当这个图为二分图时返回true. 如果我们能将一个图的节点集合分割成两个独立的子集A和B,并使图中的每一条边的两个节点一个来自A集合,一个来自B集合,我们就将这个图称为二分图. graph将会以邻接表方式给出,graph[i]表示图中与节点i相连的所有节点.每个节点都是一个在0到graph.length-1之间的整数.这图中没有自环和平行边: graph[i] 中不存在i,并且graph[i]中没有重复的值. 示例 1: 输入: [[1,3], [

数据结构(15):图 深度优先遍历(DFS)

/*-----------------------------------------------*/ /* 邻接矩阵的DFS */ // 基于 数据结构(14) 中的邻接矩阵的结构 #include <iostream> using namespace std; typedef char VertexType; typedef int EdgeType; const int MAXVEX = 100; const int INFINITY = 65535; typedef struct {

树的遍历与图的遍历

研发时候,不要受原来的术语的影响,其实就是想着原来学过的或者看过的可以解决新遇到的问题,这其实是侥幸心理,忘记原来的术语吧,那只是你创新的源泉. 遍历就是把节点按一定规则构成一个线性序列,不同的规则得到不同顺序的线性序列,仅此而已 . 算法是实际问题工作步骤的抽象,不要一味想算法,想想实际情况怎么做的,然后提取算法,然后优化. 不论怎样,要和具体的数据结构结合在一起. 一.树的遍历 对于树的遍历,有三种,就拿前序遍历来说,得到的序列不论怎么拆分(子串,就是要连续),始 终要是根左右,跟在左右前面

图的两种遍历-DFS&amp;BFS

DFS和BFS在图中的应用: 图连通性判定:路径的存在性:图中是否存在环:求图的最小生成树:求图的关键路径:求图的拓扑排序. DFS:简单的说,先一直往深处走,直到不能再深了,再从另一条路开始往深处走,直到所有路都走完: struct node { int next; //E[i].next指向图中与i同父的下一个结点 int to; //E[i].to指向图中i的子结点 }E[110]; int N; int fa[110]; //记录各点的父结点 bool vis[110]; //记录这个点

算法导论--图的遍历(DFS与BFS)

转载请注明出处:勿在浮沙筑高台http://blog.csdn.net/luoshixian099/article/details/51897538 图的遍历就是从图中的某个顶点出发,按某种方法对图中的所有顶点访问且仅访问一次.为了保证图中的顶点在遍历过程中仅访问一次,要为每一个顶点设置一个访问标志.通常有两种方法:深度优先搜索(DFS)和广度优先搜索(BFS).这两种算法对有向图与无向图均适用. 以下面无向图为例: 1.深度优先搜索(DFS) 基本步骤: 1.从图中某个顶点v0出发,首先访问v

图的遍历(BFS、DFS的邻接矩阵和邻接表实现)

当年老师给我们讲这里的时候,讲的真是云里雾里的. .其实画个图就很容易理解的事情,为什么扯那么远 我觉得 DFS其实就是树的先序遍历的强化版本 BFS是层序遍历的强化 只不过 图的实现方式比较多元化 而且不像二叉树有明确的根 操作起来相对难一些 理论其实很好理解 就是具体操作起来 每次都很晕的样子 眼高手低了又. 图的遍历是指从图中的任一顶点出发,对图中的所有顶点访问一次且只访问一次.图的遍历操作和树的遍历操作功能相似.图的遍历是图的一种基本操作,图的许多其它操作都是建立在遍历操作的基础之上.