0
点赞
收藏
分享

微信扫一扫

图的遍历dfs和bfs

芭芭蘑菇 2022-03-26 阅读 57

在这里插入图片描述
在这里插入图片描述
DenseGraph.h

#include <iostream>
#include <vector>
#include <cassert>
using namespace std;
// 使用邻接矩阵方式实现一个稠密图
class DenseGraph{
private:
    int n, m;// 节点数和边数
    bool directed; // 是否为有向图
    vector<vector<bool>> g; // 图的具体数据
public:
    // 构造函数
    DenseGraph(int n, bool directed){
        assert(n >=0);
        this->n = n;
        this->m = 0;  // 初始化没有任何边
        this->directed = directed;
        // g初始化为n*n的布尔矩阵, 每一个g[i][j]均为false, 表示没有任和边
        g =  vector<vector<bool>>(n, vector<bool>(n, false));
    }
    ~DenseGraph(){};
    int V(){return n;}  // 返回节点个数
    int E(){return m;}  // 返回边的个数
    // 向图中添加一个边
    void addEdge(int v, int w){
        assert(v >=0 && v < n);
        assert(w >=0 && w < n);
        if (hasEdge(v, w))
            return;
        g[v][w] = true;
        if (!directed)
            g[w][v] = true;
        m++;
    }

    // 验证图中是否有从v到w的边
    bool hasEdge(int v, int w){
        assert(v >=0 && v < n);
        assert(w >=0 && w < n);
        return g[v][w];
    }
    void show(){
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < n; j++) {
                cout<< g[i][j] <<"\t";
            }
            cout<<endl;
        }
    }
    // 邻边迭代器, 传入一个图和一个顶点,
    // 迭代在这个图中和这个顶点向连的所有顶点
    class adjIterator{
    private:
        DenseGraph &G; // 图G的引用
        int v; // 顶点数
        int index; // 表示索引
    public:
        // 构造函数
        adjIterator(DenseGraph &graph, int v): G(graph){
            this->v = v;
            this->index = -1;
        }
        // 返回图G中与顶点v相连接的第一个顶点
        int begin(){
            // 索引从-1开始, 因为每次遍历都需要调用一次next()
            index = -1;
            return next();
        }
        // 返回图G中与顶点v相连接的下一个顶点
        int next(){
            // 从当前index开始向后搜索, 直到找到一个g[v][index]为true
            for (index += 1; index < G.V(); index++) {
                if (G.g[v][index])
                    return index;
            }
            return -1;
        }
        //查看是否已经迭代完了图G中与顶点v相连接的所有顶点
        bool end(){
            return index >= G.V();
        }
    };
};

SparseGraph.h

#include <iostream>
#include <vector>
#include <cassert>
using namespace std;
// 使用邻接表方式实现一个稀疏图
class SparseGraph{
private:
    int n, m;// 节点数和边数
    bool directed; // 是否为有向图
    vector<vector<int>> g; // 图的具体数据
public:
    // 构造函数
    SparseGraph(int n, bool directed){
        assert(n >=0);
        this->n = n;
        this->m = 0;  // 初始化没有任何边
        this->directed = directed;
        // g初始化为n*n的布尔矩阵, 每一个g[i][j]均为false, 表示没有任和边
        g =  vector<vector<int>>(n, vector<int>());
    }
    ~SparseGraph(){};
    int V(){return n;}  // 返回节点个数
    int E(){return m;}  // 返回边的个数
    // 向图中添加一个边
    void addEdge(int v, int w){
        assert(v >=0 && v < n);
        assert(w >=0 && w < n);
        if (hasEdge(v, w))
            return;
        g[v].push_back(w);
        if (v != w && !directed)
            g[w].push_back(v);
        m++;
    }

    // 验证图中是否有从v到w的边
    bool hasEdge(int v, int w){
        assert(v >=0 && v < n);
        assert(w >=0 && w < n);
        for (int i = 0; i < g[v].size(); i++) {
            if (g[v][i] == w)
                return true;
        }
        return false;
    }
    // 显示图的信息
    void show(){
        for(int i= 0; i< n; i++){
            cout<<"vertex "<< i<<":\t";
            // [[1, 3], [0, 2, 6], [1, 3, 5]]
            for (int j = 0; j < g[i].size(); j++) {
                cout<<g[i][j]<<"\t";
            }
            cout<<endl;
        }
    }

    // 邻边迭代器, 传入一个图和一个顶点,
    // 迭代在这个图中和这个顶点向连的所有顶点
    class adjIterator{
    private:
        SparseGraph &G; // 图G的引用
        int v; // 顶点数
        int index; // 表示索引
    public:
        // 构造函数
        adjIterator(SparseGraph &graph, int v): G(graph){
            this->v = v;
            this->index = 0;
        }
        ~adjIterator(){}
        // 返回图G中与顶点v相连接的第一个顶点
        int begin(){
            index = 0;
            if (G.g[v].size())
                return  G.g[v][index];
            // 若没有顶点和v相连接, 则返回-1
            return -1;
        }
        // 返回图G中与顶点v相连接的下一个顶点

        int next(){
            index++;
            if (index < G.g[v].size())
                return  G.g[v][index];
            // 若没有顶点和v相连接, 则返回-1
            return -1;
        }
        //查看是否已经迭代完了图G中与顶点v相连接的所有顶点
        bool end(){
            return index >= G.g[v].size();
        }
    };
};


ReadGraph.h


#include <iostream>
#include <fstream>
#include <sstream>
#include <cassert>
#include <string>
using namespace std;
template <typename Graph>
class ReadGraph{
public:
     // 从文件filename中读取图的信息, 存储进图graph中
    ReadGraph(Graph &graph, const string &filename){
    ifstream file(filename);
    string line;
    int V, E;
    assert(file.is_open());
    // 第一行读取图中的节点个数和边的个数
    assert(getline(file, line));
    stringstream ss(line);
    ss>>V>>E;
    assert(V == graph.V());
    // 读取每一条边的信息
    for (int i = 0; i < E; i++) {
        assert(getline(file, line));
        stringstream ss(line);
        int a, b;
        ss >> a >> b;
        assert(a >=0 && a < V);
        assert(b >=0 && b < V);
        graph.addEdge(a, b);
    }
    }
};

testG1.txt

13 13
0 5
4 3
0 1
9 12
6 4
5 4
0 2
11 12
9 10
0 6
7 8
9 11
5 3

testG2.txt

6 8
0 1
0 2
0 5
1 2
1 3
1 4
3 4
3 5

测试

#include <iostream>
#include "ReadGraph.h"
#include "SparseGraph.h"
#include "DenseGraph.h"
using namespace std;
int main (){
    string filename = "/Users/ericli/CLionProjects/lijunshi/day13/testG1.txt";
    SparseGraph g1(13, false);
    ReadGraph<SparseGraph> readGraph1(g1, filename);
    cout<<"test G1 in Sparse Graph:" << endl;
    g1.show();
    cout<< "------" <<endl;


    DenseGraph g2(13, false);
    ReadGraph<DenseGraph> readGraph2(g2, filename);
    cout<<"test G1 in Dense Graph:" << endl;
    g2.show();
    cout<< "------" <<endl;
    //  使用两种图的存储方式读取testG2.txt文件


    filename = "/Users/ericli/CLionProjects/lijunshi/day13/testG2.txt";
    SparseGraph g3(6, false);
    ReadGraph<SparseGraph> readGraph3(g3, filename);
    cout<<"test G2 in Sparse Graph:" << endl;
    g1.show();
    cout<< "------" <<endl;


    DenseGraph g4(6, false);
    ReadGraph<DenseGraph> readGraph4(g4, filename);
    cout<<"test G2 in Dense Graph:" << endl;
    g4.show();
    cout<< "------" <<endl;
    return 0;
}

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

举报

相关推荐

0 条评论