图的广度优先搜索(BFS)和深度优先搜索(DFS)

本文通过具体的代码实现介绍了《算法导论》第四版中关于图的基本算法,包括广度优先搜索(BFS)和深度优先搜索(DFS)。通过这些算法,我们可以解决诸如路径查找等问题。

针对《算法导论》第四版 22章 基本的图算法的伪代码的实现

直接上代码

graph.h

/*
 * graph.h
 *
 *  Created on: 2017年6月25日
 *      Author: xiaoquan
 */

#ifndef GRAPH_H_
#define GRAPH_H_

#include<vector>

using namespace std;

enum Color{
    WHITE,
    GRAY,
    BLACK
};

struct Node{
    Color color;
    int d;//深度优先时是时间
    int pre;
    int f;//针对深度优先
    Node():color(WHITE),d(0),pre(0),f(0){}
};//定义节点

struct Edge{
    int u;
    int v;
    int w;
    Edge():u(0),v(0),w(0){}
    Edge(int start,int end,int weight = 0):u(start),v(end),w(weight){}
};



class Graph{
private:
    vector<Node> V;
    vector<Edge> E;
    vector<vector<Edge> >Adj;
public:
    int time;//针对深度优先,用来记录时间戳

    Graph(int v_num,int e_num);

    void addEdge(int u,int v,int w = 0);
    void BFS(int s);
    void Print_Path(int s,int v);

    void DFS();
    void DFS_Visit(int u);
};
#endif /* GRAPH_H_ */

graph.cpp

/*
 * graph.cpp
 *
 *  Created on: 2017年6月25日
 *      Author: xiaoquan
 */


#include"graph.h"
#include<queue>
#include<iostream>

using namespace std;

Graph::Graph(int v_num,int e_num){
    V.resize(v_num);
    Adj.resize(v_num);
}

void Graph::addEdge(int u,int v,int w){
    Edge *te = new Edge(u,v,w);
    E.push_back(*te);
    Adj[u-1].push_back(*te);
}
void Graph::BFS(int s){
    for(int i = 0;i < V.size();i++){
        V[i].color = WHITE;
        V[i].d = 0;
        V[i].pre = 0;
    }
    V[s-1].color = GRAY;
    queue<int> Q;
    Q.push(s);
    while(!Q.empty()){
        int u = Q.front();
        Q.pop();
        for(int i = 0;i < Adj[u-1].size();i++){
            int v = Adj[u-1][i].v;
            if(V[v-1].color == WHITE){
                V[v-1].color = GRAY;
                V[v-1].d += 1;
                V[v-1].pre = u;
                Q.push(v);

                cout << u << "->" << v << "\n";//测试用
            }
        }
        V[u-1].color = BLACK;
    }
}

void Graph::Print_Path(int s,int v){
    if(v == s)
        cout << s;
    else if(V[v-1].pre == 0){
        cout << "No path from " << s << " to " << v << "\n";
    }else{
        Print_Path(s,V[v-1].pre);
        cout << "->" << v;
    }
}

void Graph::DFS(){
    for(int i = 0;i < V.size();i++){
        V[i].color = WHITE;
        V[i].pre = 0;
    }

    time = 0;
    for(int u = 1;u <= V.size();u++){
        if(V[u-1].color == WHITE)
            DFS_Visit(u);
    }
}
void Graph::DFS_Visit(int u){
    time++;
    V[u-1].d = time;
    V[u-1].color = GRAY;
    for(int i = 0;i < Adj[u-1].size();i++){
        int v = Adj[u-1][i].v;
        if(V[v-1].color == WHITE){
            cout << u << "->" << v << "\n";//测试用

            V[v-1].pre = u;
            DFS_Visit(v);
        }
    }
    V[u-1].color = BLACK;
    time++;
    V[u-1].f = time;
}

test.c

#include"graph.h"
using namespace std;
int main(){
    Graph G(6,8);
    G.addEdge(1,2);
    G.addEdge(1,4);
    G.addEdge(2,5);
    G.addEdge(3,5);
    G.addEdge(3,6);
    G.addEdge(4,2);
    G.addEdge(5,4);
    G.addEdge(6,6);

    G.BFS(1);
    G.Print_Path(1,6);

    G.DFS();
    return 0;
}

其他详见github

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值