算法基础——DFS与BFS初探

目录

递归解决DFS

栈解决DFS

队列解决BFS


递归解决DFS

输入为邻接表格式

顶点编号 与顶点相交的顶点数 相交的顶点编号

//递归DFS
/*
6
1 2 2 3
2 2 3 4
3 1 5
4 1 6
5 1 6
6 0
*/
#include <iostream>
using namespace std;
static const int N = 100;
static const int WHITE = 0;//未访问的点
static const int GRAY = 1;//访问过的点
static const int BLACK = 2;//访问结束的点
int n,M[N][N];
int color[N],d[N],f[N],tt;//f记录访问结束时刻

void dfs_visit(int u){
    color[u]=GRAY;//标记访问过的点
    d[u]=++tt;//最初访问的点
    for(int v=0;v<n;v++){
        if(M[u][v]==0){
            continue;
        }
        if(color[v]==WHITE){//如果结点未被访问
            dfs_visit(v);
        }
    }
    color[u] = BLACK;//将u标记为访问结束
    f[u] = ++tt;//访问结束时刻
}

void dfs(){
    //先进行初始化
    for(int i=0;i<n;i++){
        color[i]=WHITE;//标记为未访问
    }
    tt = 0;
    for(int u=0;u<n;u++){
        if(color[u]==WHITE){
            dfs_visit(u);
        }
    }
    cout<<"the name of vertex"<<" "<<"beginning"<<" "<<"ending"<<endl;
    for(int u=0;u<n;u++){
        cout<<u+1<<" "<<d[u]<<" "<<f[u]<<" "<<endl;
    }

}
int main(){

    int u,v,k;
    cin>>n;
    for(int i=0;i<n;i++){
        for(int j=0;j<n;j++){
            M[i][j]=0;
        }
    }

    for(int i=0;i<n;i++){
        cin>>u>>k;
        u--;//记得转换成0为开始时刻的格式
        for(int j=0;j<k;j++){
            cin>>v;
            v--;
            M[u][v]=1;
        }
    }

    // for(int i=0;i<n;i++){
    //     for(int j=0;j<n;j++){
    //         cout<<M[i][j]<<" ";
    //     }
    //     cout<<endl;
    // }

    dfs();

    return 0;
}

栈解决DFS

//DFS栈
/*
6
1 2 2 3
2 2 3 4
3 1 5
4 1 6
5 1 6
6 0
*/
#include <iostream>
#include <stack>
using namespace std;
static const int N = 100;
static const int WHITE = 0;//未访问的点
static const int GRAY = 1;//访问过的点
static const int BLACK = 2;//访问结束的点
int n,M[N][N];
int color[N],d[N],f[N],tt;//f记录访问结束时刻
int nt[N];

//获取与编号顺序u相同的v
int next(int u){
    for(int v=nt[u];v<n;v++){
        nt[u]=v+1;
        if(M[u][v])
            return v;
    }
    return -1;
}

void dfs_init(int r){
    for(int i=0;i<n;i++){
        nt[i]=0;
    }
    stack<int> S;
    S.push(r);
    color[r]=GRAY;
    d[r] = ++tt;
    while(!S.empty()){
        int u=S.top();
        int v=next(u);//获取与u相邻的结点v
        if(v!=-1){//没有与之相邻的结点
            if(color[v]==WHITE){
                color[v]=GRAY;//标记为访问过的结点
                d[v]=++tt;
                S.push(v);
            }
        }else{
            S.pop();
            color[u]=BLACK;
            f[u]=++tt;//记录访问结束的时间
        }
        
    }
}

void dfs(){
    //先进行初始化
    for(int i=0;i<n;i++){
        color[i]=WHITE;
        nt[i]=0;
    }
    tt = 0;
    for(int u=0;u<n;u++){
        if(color[u]==WHITE){
            dfs_init(u);
        }
    }
    cout<<"the name of vertex"<<" "<<"beginning"<<" "<<"ending"<<endl;
    for(int i=0;i<n;i++){
        cout<<i+1<<" "<<d[i]<<" "<<f[i]<<endl;
    }
}

int main(){
    int u,v,k;
    cin>>n;
    for(int i=0;i<n;i++){
        for(int j=0;j<n;j++){
            M[i][j]=0;
        }
    }

    for(int i=0;i<n;i++){
        cin>>u>>k;
        u--;//记得转换成0为开始时刻的格式
        for(int j=0;j<k;j++){
            cin>>v;
            v--;
            M[u][v]=1;
        }
    }

    // for(int i=0;i<n;i++){
    //     for(int j=0;j<n;j++){
    //         cout<<M[i][j]<<" ";
    //     }
    //     cout<<endl;
    // }

    dfs();


    return 0;
}

队列解决BFS

//BFS队列
/*
6
1 2 2 3
2 2 3 4
3 1 5
4 1 6
5 1 6
6 0
*/
#include <iostream>
#include <queue>
using namespace std;

static const int N=100;
static const int INFTY=(1<<21);//定义无穷大的数

int n,M[N][N];
int d[N];//通过距离管理访问状态

void bfs(int s){
    queue<int> q;
    q.push(s);
    for(int i=0;i<n;i++){
        d[i]=INFTY;//先将距离初始化为无穷大
    }
    d[s]=0;
    int u;
    while(!q.empty()){
        u = q.front();
        q.pop();
        for(int v=0;v<n;v++){
            if(M[u][v]==0){
                continue;
            }
            if(d[v]!=INFTY){
                continue;
            }
            d[v]=d[u]+1;
            q.push(v);
        }
    }
    cout<<"the number of vertex"<<" "<<"distance"<<endl;
    for(int i=0;i<n;i++){
        //顶点编号 顶点到顶点1的距离
        cout<<i+1<<" "<<((d[i]==INFTY)?(-1):d[i])<<endl;
    }
}

int main(){
    
    int u,v,k;
    cin>>n;
    for(int i=0;i<n;i++){
        for(int j=0;j<n;j++){
            M[i][j]=0;
        }
    }

    for(int i=0;i<n;i++){
        cin>>u>>k;
        u--;//记得转换成0为开始时刻的格式
        for(int j=0;j<k;j++){
            cin>>v;
            v--;
            M[u][v]=1;
        }
    }

    bfs(0);

    return 0;
}
发布了287 篇原创文章 · 获赞 297 · 访问量 12万+

猜你喜欢

转载自blog.csdn.net/qq_41895747/article/details/104250838