C++ 非STL数据结构学习——1.4 图

一般而言,图的实现有邻接矩阵和邻接表两种。


1. 邻接矩阵

#include <iostream>
#include <vector>

class Graph {
private:
    int V; // 顶点数量
    std::vector<std::vector<int>> adjMatrix; // 邻接矩阵
    std::vector<bool> visited; // 记录顶点是否被访问过

public:
    Graph(int vertices) : V(vertices) {
        adjMatrix.resize(V, std::vector<int>(V, 0));
        visited.resize(V, false);
    }

    void addEdge(int u, int v) {
        // 在顶点u到v之间添加一条有向边
        adjMatrix[u][v] = 1;
    }

    void printGraph() {
        std::cout << "Graph adjacency matrix:" << std::endl;
        for (int i = 0; i < V; ++i) {
            for (int j = 0; j < V; ++j) {
                std::cout << adjMatrix[i][j] << " ";
            }
            std::cout << std::endl;
        }
    }
    //图的深度优先遍历
    void DFS(int startVertex) {
        visited[startVertex] = true;
        std::cout << startVertex << " ";

        for (int i = 0; i < V; ++i) {
            if (adjMatrix[startVertex][i] == 1 && !visited[i]) {
                DFS(i);
            }
        }
    }

    void DFSTraversal() {
        std::cout << "Depth First Traversal starting from vertex 0:" << std::endl;
        DFS(0);
        std::cout << std::endl;
    }
    //图的广度优先遍历
    void BFS(int startVertex) {
        std::queue<int> q;
        q.push(startVertex);
        visited[startVertex] = true;

        while (!q.empty()) {
            int currentVertex = q.front();
            q.pop();
            std::cout << currentVertex << " ";

            for (int i = 0; i < V; ++i) {
                if (adjMatrix[currentVertex][i] == 1 && !visited[i]) {
                    q.push(i);
                    visited[i] = true;
                }
            }
        }
    }

    void BFSTraversal() {
        std::cout << "Breadth First Traversal starting from vertex 0:" << std::endl;
        BFS(0);
        std::cout << std::endl;
    }
};
};

2. 邻接表

#include <iostream>
#include <vector>

class Graph {
private:
    int V; // 顶点数量
    std::vector<std::vector<int>> adjList; // 邻接表
    std::vector<bool> visited; // 记录顶点是否被访问过

public:
    Graph(int vertices) : V(vertices) {
        adjList.resize(V);
        visited.resize(V, false);
    }

    void addEdge(int u, int v) {
        // 在顶点u的邻接表中添加顶点v
        adjList[u].push_back(v);
    }

    void printGraph() {
        std::cout << "Graph adjacency list:" << std::endl;
        for (int i = 0; i < V; ++i) {
            std::cout << i << " -> ";
            for (int j : adjList[i]) {
                std::cout << j << " ";
            }
            std::cout << std::endl;
        }
    }
    //深度优先遍历
    void DFSRecursive(int startVertex) {
        visited[startVertex] = true;
        std::cout << startVertex << " ";

        for (int neighbor : adjList[startVertex]) {
            if (!visited[neighbor]) {
                DFSRecursive(neighbor);
            }
        }
    }

    // 深度优先遍历入口
    void DFSTraversal() {
        std::cout << "Depth First Traversal starting from vertex 0:" << std::endl;
        DFSRecursive(0);
        std::cout << std::endl;
    }
    // 广度优先搜索
    void BFS(int startVertex) {
        std::queue<int> q;
        q.push(startVertex);
        visited[startVertex] = true;

        while (!q.empty()) {
            int currentVertex = q.front();
            q.pop();
            std::cout << currentVertex << " ";

            for (int neighbor : adjList[currentVertex]) {
                if (!visited[neighbor]) {
                    q.push(neighbor);
                    visited[neighbor] = true;
                }
            }
        }
    }

    // 广度优先搜索入口
    void BFSTraversal() {
        std::cout << "Breadth First Traversal starting from vertex 0:" << std::endl;
        BFS(0);
        std::cout << std::endl;
    }
};

P1. 洛谷p3916图的遍历

#include<iostream>
#include<vector>
#include<queue>
using namespace std;

class Graph {
private:
    int V; // 顶点数量
    std::vector<std::vector<int>> adjList; // 邻接表
    std::vector<bool> visited; // 记录顶点是否被访问过
    vector<int> maxspot;//记录每个点能到达的最大点的编号

public:
    Graph(int vertices) : V(vertices) {
        adjList.resize(V+1);
        visited.resize(V+1, false);//只用于初始化,不可像fill一样用
        maxspot.resize(V+1);
        for(int i=0;i<=V;i++)
        maxspot[i]=i;//初始化为自己
    }

    void addEdge(int u, int v) {
        // 在顶点u的邻接表中添加顶点v
        adjList[u].push_back(v);
    }

    void clearvis()
    {
        for(int i=1;i<=V;i++) visited[i]=false;
    }

    void printans()
    {
        for(int i=1;i<=V;i++)
        cout<<maxspot[i]<<" ";
    }

    void printGraph() {
        std::cout << "Graph adjacency list:" << std::endl;
        for (int i = 1; i < V+1; ++i) {
            std::cout << i << " -> ";
            for (int j : adjList[i]) {
                std::cout << j << " ";
            }
            std::cout << std::endl;
        }
    }
    //深度优先遍历
    void DFSRecursive(int startVertex) {
        visited[startVertex] = true;
        std::cout << startVertex << " ";

        for (int neighbor : adjList[startVertex]) {
            if (!visited[neighbor]) {
                DFSRecursive(neighbor);
            }
        }
    }

    // 深度优先遍历入口
    void DFSTraversal() {
        std::cout << "Depth First Traversal starting from vertex 0:" << std::endl;
        DFSRecursive(0);
        std::cout << std::endl;
    }
    // 广度优先搜索
    void BFS(int startVertex) {
        int record=startVertex;
        std::queue<int> q;
        q.push(startVertex);
        visited[startVertex] = true;

        while (!q.empty()) {
            int currentVertex = q.front();
            q.pop();
            if(currentVertex>maxspot[record]) maxspot[record]=currentVertex;
            //std::cout << currentVertex << " ";

            for (int neighbor : adjList[currentVertex]) {
                if (!visited[neighbor]) {
                    q.push(neighbor);
                    visited[neighbor] = true;
                }
            }
        }
        //cout<<endl;
    }

    // 广度优先搜索入口
    void BFSTraversal() {
        std::cout << "Breadth First Traversal starting from vertex 0:" << std::endl;
        BFS(0);
        std::cout << std::endl;
    }
};

int main()
{
    int n,m;cin>>n>>m;
    Graph mygraph(n);
    for(int i=1;i<=m;i++)
    {
        int a,b;
        cin>>a>>b;
        mygraph.addEdge(a,b);
    }
    //mygraph.printGraph();
    for(int i=1;i<=n;i++)
    {
        mygraph.BFS(i);
        mygraph.clearvis();
    }
    mygraph.printans();
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值