IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> c++ 关于bfs和dfs的相对统一写法 -> 正文阅读

[数据结构与算法]c++ 关于bfs和dfs的相对统一写法

文章目录

简介

  • 有向图bfs
  • 有向图dfs
  • 有向图拓扑排序

着重看看bfs 和 dfs 实现的差异性, 了解二者的相似和不同

代码

#include <iostream>
#include <vector>
#include <algorithm>
#include <chrono>
#include <stack>
#include <queue>
#include <numeric>

using namespace std;

struct Edge {
    int to;
    int weight;
};

struct Vertex {
    vector<Edge> adjacent;
};

// 无向图
class Graph {
public:
    int n{};
    vector<Vertex> nodes;

protected:
    [[nodiscard]] virtual Graph *clone() const {
        return new Graph(*this);
    }

public:
    Graph() = default;

    Graph(const Graph &other) {
        this->n = other.n;
        this->nodes = other.nodes;
    }

    virtual void addEdge(int v, int w, int weight = 0) {
        nodes[v].adjacent.push_back({.to = w, .weight = weight});
        nodes[w].adjacent.push_back({.to = v, .weight = weight});
    }

    void addAllEdge(int n, vector<vector<int>> &edges) {
        this->n = n;
        nodes.resize(n);
        for (auto &vec: edges) {
            int from = vec[0];
            int to = vec[1];
            int weight = 0;
            if (vec.size() >= 3) {
                weight = vec[2];
            }
            addEdge(from, to, weight);
        }
    }

    [[nodiscard]] int Vex() const {
        return n;
    }

    [[nodiscard]] const vector<Edge> &getEdges(int v) const {
        return nodes[v].adjacent;
    }

    [[nodiscard]] virtual Graph *reverse() const {
        auto g = this->clone();
        return g;
    }

};

// 有向图
class DiGraph : public Graph {
public:
    DiGraph() = default;

    [[nodiscard]] Graph *reverse() const override {
        Graph* g = new DiGraph;
        g->n = this->n;
        g->nodes.resize(g->n);

        for (int from = 0; from < Vex(); from++) {
            for (auto &e: getEdges(from)) {
                int to = e.to;
                int weight = e.to;
                g->addEdge(to, from, weight);
            }
        }
        return g;
    }

    void addEdge(int v, int w, int weight) override {
        nodes[v].adjacent.push_back({.to = w, .weight = weight});
    }

private:
    [[nodiscard]] Graph *clone() const override {
        return new DiGraph(*this);
    }
};

class QAbs {
public:
    virtual void enQ(int id) = 0;

    virtual int deQ() = 0;

    virtual bool empty() = 0;
};

class DfsQ : public QAbs {
private:
    stack<int> q;

public:
    void enQ(int id) override {
        q.push(id);
    }

    int deQ() override {
        int id = q.top();
        q.pop();
        return id;
    }

    bool empty() override {
        return q.empty();
    }
};

class BfsQ : public QAbs {
private:
    queue<int> q;
public:
    void enQ(int id) override {
        q.push(id);
    }

    int deQ() override {
        int id = q.front();
        q.pop();
        return id;
    }

    bool empty() override {
        return q.empty();
    }
};

enum class Order {
    BFS = 0,
    DFS = 1,
};

class TraversalAbs {
public:
    Graph *g;
    vector<bool> known;
    QAbs *q;

protected:
    virtual void pre(int v) {
        cout << v << "\t";
    }

    virtual void afterOneTraversal() {
        cout << endl;
    }

    virtual void afterTraversal() {
    }

public:
    TraversalAbs(Graph *g, Order order) : g(g), known(g->Vex()) {
        if (order == Order::BFS) {
            q = new BfsQ;
        } else {
            q = new DfsQ;
        }
    }

    void traversal(int v) {
        known[v] = true;
        q->enQ(v);
        while (!q->empty()) {
            int id = q->deQ();
            // 先序
            pre(id);
            for (auto w: g->getEdges(id)) {
                int to = w.to;
                if (known[to]) {
                    continue;
                }
                known[to] = true;
                q->enQ(to);
            }
        }
        afterOneTraversal();
    }

    void traversal() {
        for (int i = 0; i < g->Vex(); i++) {
            if (known[i]) {
                continue;
            }
            traversal(i);
        }
        afterTraversal();
    }
};

class DfsTopology : public TraversalAbs {
public:
    explicit DfsTopology(Graph *g) : TraversalAbs(g, Order::DFS) {}

private:
    stack<int> st;
    stack<int> ans;

protected:
    void pre(int v) override {
        st.push(v);
    }

    void afterTraversal() override {
        while (!ans.empty()) {
            cout << ans.top() << "\t";
            ans.pop();
        }
        cout << endl;
    }

    void afterOneTraversal() override {
        while (!st.empty()) {
            ans.push(st.top());
            st.pop();
        }
    }
};


int main() {
    vector<vector<int>> data = {
            {0, 1, 2},
            {1, 2, 2},
            {2, 3, 1},
            {3, 4, 2},
            {0, 4, 3},
    };
    auto g = new DiGraph;
    g->addAllEdge(5, data);

    auto rg = g->reverse();

    // bfs 遍历
    TraversalAbs btr(g, Order::BFS);
    btr.traversal(0);

    // dfs 遍历
    TraversalAbs dtr(g, Order::DFS);
    dtr.traversal(0);

    // 拓扑排序
    auto df = new DfsTopology(rg);
    df->traversal();
}

输出

在这里插入图片描述

c++ 关于bfs和dfs的相对统一写法
c++ 关于bfs和dfs的相对统一写法
c++ 关于bfs和dfs的相对统一写法
c++ 关于bfs和dfs的相对统一写法
c++ 关于bfs和dfs的相对统一写法
c++ 关于bfs和dfs的相对统一写法
c++ 关于bfs和dfs的相对统一写法
c++ 关于bfs和dfs的相对统一写法
c++ 关于bfs和dfs的相对统一写法
c++ 关于bfs和dfs的相对统一写法

  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2022-09-04 01:36:44  更:2022-09-04 01:39:37 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/25 21:21:20-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码