有向图的邻接表
代码实现
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <string>
#include <vector>
#include <list>
using namespace std;
class Digraph {
public:
// 从配置文件读取定点和边的信息,生成邻接表
void readFile(string filePath) {
FILE *pf = fopen(filePath.c_str(), "r");
if (pf == nullptr) {
perror("read file");
throw "error";
}
// 占用第0号位置
vertics.emplace_back("");
while (!feof(pf)) {
char line[1024] = {0};
fgets(line, 1024, pf); // 读取节点的信息
// 增加一个节点信息
string linestr(line);
vertics.emplace_back(linestr.substr(0, linestr.size() - 1));
fgets(line, 1024, pf); // 读取边的信息
char* vertic_no = strtok(line, ",");
while (vertic_no != nullptr) {
vertics.back().adjList_.emplace_back(atoi(vertic_no));
vertic_no = strtok(nullptr, ",");
}
}
fclose(pf);
}
// 输出邻接表信息
void show() {
for (int i = 1; i < vertics.size(); i++) {
cout << vertics[i].data_ << ":";
for (auto no : vertics[i].adjList_) {
cout << no << " ";
}
cout << endl;
}
cout << endl;
}
private:
// 顶点类型
struct Vertic {
Vertic(string data): data_(data) {}
string data_; // 存储定点的信息
list<int> adjList_; // 邻接链表结构
};
private:
vector<Vertic> vertics; // 邻接表结构
};
int main() {
Digraph graph;
graph.readFile("data.txt");
graph.show();
return 0;
}
测试
data.txt文件内容
A
2,4,5
B
6
C
2,4
D
3,8
E
8
F
7,9
G
2,3
H
0
I
8
➜ 有向图邻接表 git:(main) ✗ g++ main.cpp -o main
➜ 有向图邻接表 git:(main) ✗ ./main
A:2 4 5
B:6
C:2 4
D:3 8
E:8
F:7 9
G:2 3
H:0
I:8
图的深度和广度优先遍历
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <string>
#include <vector>
#include <list>
#include <queue>
using namespace std;
class Digraph {
public:
// 从配置文件读取定点和边的信息,生成邻接表
void readFile(string filePath) {
FILE *pf = fopen(filePath.c_str(), "r");
if (pf == nullptr) {
perror("read file");
throw "error";
}
// 占用第0号位置
vertics.emplace_back("");
while (!feof(pf)) {
char line[1024] = {0};
fgets(line, 1024, pf); // 读取节点的信息
// 增加一个节点信息
string linestr(line);
vertics.emplace_back(linestr.substr(0, linestr.size() - 1));
fgets(line, 1024, pf); // 读取边的信息
char* vertic_no = strtok(line, ",");
while (vertic_no != nullptr) {
int vex = atoi(vertic_no);
if (vex > 0) {
vertics.back().adjList_.emplace_back(atoi(vertic_no));
}
vertic_no = strtok(nullptr, ",");
}
}
fclose(pf);
}
// 输出邻接表信息
void show() {
for (int i = 1; i < vertics.size(); i++) {
cout << vertics[i].data_ << ":";
for (auto no : vertics[i].adjList_) {
cout << no << " ";
}
cout << endl;
}
cout << endl;
}
// 图的深度优先遍历
void dfs() {
vector<bool> visited(vertics.size(), false);
dfs(1, visited);
cout << endl;
}
// 广度优先遍历
void bfs() {
vector<bool> visited(vertics.size(), false); // 标识当前节点是否被遍历过
queue<int> que;
que.push(1);
visited[1] = true;
while (!que.empty()) {
int cur_no = que.front();
que.pop();
cout << vertics[cur_no].data_ << " ";
for (auto no : vertics[cur_no].adjList_) {
if (!visited[no]) {
que.push(no);
visited[no] = true;
}
}
}
cout << endl;
}
private:
// 深度优先遍历的递归接口
void dfs(int start, vector<bool>& visited) {
if (visited[start]) {
return; // 已经遍历过了
}
cout << vertics[start].data_ << " ";
visited[start] = true;
// 递归遍历下一层节点
for (auto no : vertics[start].adjList_) {
dfs(no, visited);
}
}
private:
// 顶点类型
struct Vertic {
Vertic(string data): data_(data) {}
string data_; // 存储定点的信息
list<int> adjList_; // 邻接链表结构
};
private:
vector<Vertic> vertics; // 邻接表结构
};
int main() {
Digraph graph;
graph.readFile("data.txt");
graph.show();
graph.dfs();
graph.bfs();
return 0;
}
测试
➜ 有向图邻接表 git:(main) ✗ ./main
A:2 4 5
B:6
C:2 4
D:3 8
E:8
F:7 9
G:2 3
H:
I:8
A B F G C D H I E
A B D E F C H G I