关于使用Vector容器建图以及BFS、DFS遍历

关于使用Vector容器建图以及BFS、DFS遍历

Vector建图是真的简单…多的不谈,直接上代码!

//
//  main.cpp
//  Created on 2020/10/24.
//

#include <iostream>
#include <queue>
#include <vector>
using namespace std;
const int Max_Len = 100 ;//最多100个节点
int Visited[Max_Len] ;//标记数组,节点是否被访问
vector<int > v [Max_Len];
int n , e;//实际节点数,边数

void Create(){
    cin >> n ;
    for(int i = 0 ;i<n ;i++){//初始化
        v[i].clear();
    }
    cin >> e ;
    while (e > 0){
        int v1 ,v2 ;
        cin >>v1 >> v2 ;//输入边
        v[v1].push_back(v2);//在v1 节点后面插入,代表已经链接
        v[v2].push_back(v1);//无向图,需要插入两遍(有向图不用)
        e-- ;
    }
}

void BFS(int x){//BFS借助队列
    queue<int >q ;
    q.push(x);
    Visited[x] = 1 ;//标志已经访问过
    while (!q.empty()){
        int u = q.front() ;
        q.pop();
        cout << u << " ";
        for(int i = 0 ;i<v[u].size() ;i++ ){//小小需要注意,这里i小于的是当前节点为根节点 的那一行 的长度;
            int p = v[u][i];
            if(Visited[p] == 0){
                q.push(p);
                Visited[p] = 1 ;
            }
        }
    }
    cout << endl ;
}
int num = 0;
void BFSTravel(){//这里是为了防止 所给的图不是连通图 ;同时可以利用BFS来求最大连通子图的个数
    memset(Visited, 0, sizeof(Visited));
    for(int i = 0 ;i< n ;i++ ){
        if(Visited[i] == 0 ){
            num ++ ;
            BFS(i);
        }
    }
    cout << "最大连通子图个数:"<< num << endl ;
}
void DFS(int x ){//DFS用递归——不管是图还是树,跟深度联系的,很多都可以用递归,简单!
    Visited[x] = 1 ;
    cout << x << " ";
    for(int i = 0 ;i < v[x].size(); i ++ ){
        int p = v[x][i];
        if(Visited[p] == 0 ){
            DFS(p);
        }
    }
}
void DFSTravel(){//原理相同,同样可以求最大连通子图
    memset(Visited, 0, sizeof(Visited));
    for(int i = 0 ;i< n ;i++ ){
        if(Visited[i] == 0 ){
            DFS(i);
        }
    }
}


int main() {
    Create();
    cout << "BFS: ";BFSTravel();
    
    cout << "DFS: ";DFSTravel();
    cout << endl ;
    
    return 0;
}

有啥问题欢迎大家私信,大家一起学习!!

  • 3
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
好的,我可以帮你回答这个问题。 首先,我们来了解一下的基本概念。是由若干个顶点和边组成的一种数据结构,用于描述事物之间的关系。顶点表示事物,边表示它们之间的关系。根据边的性质,可以分为有向和无向。 接下来,我们可以使用邻接矩阵或邻接表来存储的信息。 邻接矩阵是一个二维数组,每个元素表示两个顶点之间是否有边。如果有边,则对应元素的值为1,否则为0。 邻接表是由若干个链表组成的数据结构,每个链表表示一个顶点,链表中存储和该顶点相连的所有边。 基于这些概念,我们可以实现的基本操作。下面是一个C++的示例代码: ```c++ #include <iostream> #include <vector> #include <queue> #include <stack> using namespace std; // 定义邻接表中的结构体 struct Edge { int to; // 目标顶点 int weight; // 边的权值 Edge(int t, int w) : to(t), weight(w) {} }; // 使用邻接表存储 class Graph { private: int n; // 顶点数 vector<vector<Edge>> adj; // 邻接表 public: // 构造函数 Graph(int num) : n(num), adj(num) {} // 添加边 void addEdge(int u, int v, int w) { adj[u].push_back(Edge(v, w)); adj[v].push_back(Edge(u, w)); // 如果是无向,则需要加上这行代码 } // 求每个顶点的度 void printDegree() { for (int i = 0; i < n; i++) { cout << "Vertex " << i << " degree: " << adj[i].size() << endl; } } // DFS void dfs(int start) { vector<bool> visited(n, false); stack<int> s; s.push(start); while (!s.empty()) { int cur = s.top(); s.pop(); if (!visited[cur]) { visited[cur] = true; cout << cur << " "; for (auto& e : adj[cur]) { if (!visited[e.to]) { s.push(e.to); } } } } cout << endl; } // BFS void bfs(int start) { vector<bool> visited(n, false); queue<int> q; q.push(start); while (!q.empty()) { int cur = q.front(); q.pop(); if (!visited[cur]) { visited[cur] = true; cout << cur << " "; for (auto& e : adj[cur]) { if (!visited[e.to]) { q.push(e.to); } } } } cout << endl; } // 删除顶点及相关边,并进行DFS void removeVertex(int x) { if (x < 0 || x >= n) { cout << "Vertex " << x << " does not exist" << endl; return; } vector<bool> visited(n, false); stack<int> s; s.push(x); while (!s.empty()) { int cur = s.top(); s.pop(); if (!visited[cur]) { visited[cur] = true; for (int i = 0; i < adj[cur].size(); i++) { if (adj[cur][i].to == x) { adj[cur].erase(adj[cur].begin() + i); i--; } else { int v = adj[cur][i].to; if (!visited[v]) { s.push(v); } } } } } adj[x].clear(); cout << "After removing vertex " << x << ":" << endl; dfs(0); } // 判断是否连通 bool isConnected() { vector<bool> visited(n, false); stack<int> s; s.push(0); while (!s.empty()) { int cur = s.top(); s.pop(); if (!visited[cur]) { visited[cur] = true; for (auto& e : adj[cur]) { if (!visited[e.to]) { s.push(e.to); } } } } for (bool v : visited) { if (!v) { return false; } } return true; } }; int main() { int n, e; cout << "Enter the number of vertices and edges: "; cin >> n >> e; Graph g(n); cout << "Enter the edges (u v w):" << endl; for (int i = 0; i < e; i++) { int u, v, w; cin >> u >> v >> w; g.addEdge(u, v, w); } // 求每个顶点的度 g.printDegree(); // DFS cout << "DFS traversal: "; g.dfs(0); // BFS cout << "BFS traversal: "; g.bfs(0); // 删除顶点及相关边,进行DFS int x; cout << "Enter a vertex to remove: "; cin >> x; g.removeVertex(x); // 判断是否连通 if (g.isConnected()) { cout << "The graph is connected" << endl; } else { cout << "The graph is not connected" << endl; } return 0; } ``` 这段代码中,我们使用了邻接表来存储的信息。在构造函数中,我们创了一个大小为n的vector,每个元素都是一个vector<Edge>,表示一个顶点和与之相连的所有边。 addEdge函数用于添加边,我们使用了无向的方式,即同时在u和v之间添加一条边。 printDegree函数用于求每个顶点的度,即与之相连的边的数量。我们遍邻接表中每个元素,计算它的大小即可。 dfs函数用于进行DFS。我们使用一个栈来存储遍的顺序,每次取出栈顶元素,并将其标记为已访问。然后遍该顶点相连的所有边,将它们加入栈中。 bfs函数用于进行BFS。我们使用一个队列来存储遍的顺序,每次取出队首元素,并将其标记为已访问。然后遍该顶点相连的所有边,将它们加入队列中。 removeVertex函数用于删除顶点及相关边,并进行DFS。我们使用一个栈来进行DFS,将所有和顶点x相连的边删除即可。最后,我们清空顶点x的信息,并进行一次DFS。 isConnected函数用于判断是否连通。我们使用DFS来判断,如果所有顶点都被访问过,则说明是连通的。 以上就是一个基本的的实现,希望能对你有所帮助!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值