写一段C++代码,以邻接表为存储结构,实现连通无向图的深度优先和广度优先遍历。以用户指定的结点为起点,分别输出每种遍历下的结点访问序列和相应生成树的边集。
时间: 2023-12-09 15:11:46 浏览: 88
好的,以下是实现连通无向图深度优先和广度优先遍历的C++代码,使用邻接表为存储结构:
```c++
#include <iostream>
#include <vector>
#include <queue>
using namespace std;
const int MAXN = 100; // 图的最大结点数
struct Edge {
int to; // 边的终点
int next; // 指向下一条边的指针
};
int head[MAXN]; // 邻接表的头指针数组
Edge edges[MAXN * 2]; // 存储所有边的数组
int edge_cnt = 0; // 边的计数器
void add_edge(int u, int v) { // 添加一条边
edges[++edge_cnt].to = v;
edges[edge_cnt].next = head[u];
head[u] = edge_cnt;
}
vector<int> dfs_seq; // 存储深度优先遍历序列
vector<Edge> dfs_tree; // 存储深度优先生成树的边集
void dfs(int u, int pre) { // 深度优先遍历
dfs_seq.push_back(u);
for (int i = head[u]; i; i = edges[i].next) {
int v = edges[i].to;
if (v != pre) {
dfs_tree.push_back(edges[i]);
dfs(v, u);
}
}
}
vector<int> bfs_seq; // 存储广度优先遍历序列
vector<Edge> bfs_tree; // 存储广度优先生成树的边集
void bfs(int start) { // 广度优先遍历
queue<int> q;
q.push(start);
vector<bool> vis(MAXN, false); // 记录每个结点是否被访问过
while (!q.empty()) {
int u = q.front();
q.pop();
bfs_seq.push_back(u);
vis[u] = true;
for (int i = head[u]; i; i = edges[i].next) {
int v = edges[i].to;
if (!vis[v]) {
bfs_tree.push_back(edges[i]);
q.push(v);
vis[v] = true;
}
}
}
}
int main() {
int n, m;
cin >> n >> m; // 输入结点数和边数
for (int i = 1; i <= m; i++) { // 输入边
int u, v;
cin >> u >> v;
add_edge(u, v);
add_edge(v, u); // 无向图,要加上反向边
}
int start;
cin >> start; // 输入起点
dfs(start, -1); // 深度优先遍历
bfs(start); // 广度优先遍历
cout << "深度优先遍历序列:";
for (int i = 0; i < dfs_seq.size(); i++) {
cout << dfs_seq[i] << ' ';
}
cout << endl;
cout << "深度优先生成树的边集:";
for (int i = 0; i < dfs_tree.size(); i++) {
cout << dfs_tree[i].to << ' ';
}
cout << endl;
cout << "广度优先遍历序列:";
for (int i = 0; i < bfs_seq.size(); i++) {
cout << bfs_seq[i] << ' ';
}
cout << endl;
cout << "广度优先生成树的边集:";
for (int i = 0; i < bfs_tree.size(); i++) {
cout << bfs_tree[i].to << ' ';
}
cout << endl;
return 0;
}
```
注意,由于输入结点编号不一定是连续的,所以使用邻接表时需要动态分配内存,可以使用`vector<int>`代替普通数组。同时,由于无向图每条边需要建立反向边,所以在`add_edge()`函数里要加上两个`edges`元素。
阅读全文