#include<iostream>
using namespace std;
const int MaxSize = 10;
// 用于记录顶点是否被访问过的数组,初始化为0表示均未被访问
int visited[10] = { 0 };
// 定义图的类模板,DataType为顶点的数据类型,可以是各种类型(如这里的char等)
template<typename DataType>
class MGraph {
public:
// 构造函数,用于初始化图,传入顶点数组、顶点数量和边的数量
MGraph(DataType a[], int n, int e);
// 析构函数(这里为空实现,可根据实际情况补充资源释放等操作)
~MGraph() {};
// 深度优先遍历函数,从指定顶点开始遍历图
void DFTraverse(int v);
// 广度优先遍历函数,从指定顶点开始遍历图
void BFTraverse(int v);
private:
// 存储图的顶点的数组
DataType vertex[MaxSize];
// 存储图的边的二维数组,edge[i][j]表示顶点i和顶点j之间是否有边相连
int edge[MaxSize][MaxSize];
// 记录图的顶点数量
int vertexNum;
// 记录图的边的数量
int edgeNum;
};
// MGraph类模板的构造函数的实现
template<typename DataType>
MGraph<DataType>::MGraph(DataType a[], int n, int e) {
int i, j, k;
// 初始化顶点数量
vertexNum = n;
// 初始化边的数量
edgeNum = e;
// 将传入的顶点数组元素赋值给图的顶点数组
for (i = 0; i < vertexNum; i++)
vertex[i] = a[i];
// 初始化边的二维数组,将所有元素置为0,表示初始时没有边相连
for (i = 0; i < vertexNum; i++)
for (j = 0; j < vertexNum; j++)
edge[i][j] = 0;
// 根据输入的边的信息,设置边的二维数组中对应位置为1,表示有边相连
// 由于是无向图,所以edge[i][j]和edge[j][i]都要设置为1
for (k = 0; k < edgeNum; k++) {
cin >> i >> j;
edge[i][j] = 1;
edge[j][i] = 1;
}
}
// MGraph类模板的深度优先遍历函数的实现
template<typename DataType>
void MGraph<DataType>::DFTraverse(int v) {
// 先输出当前访问的顶点
cout << vertex[v];
// 将当前顶点标记为已访问
visited[v] = 1;
// 遍历所有顶点,查找与当前顶点有边相连且未被访问的顶点,然后递归地进行深度优先遍历
for (int j = 0; j < vertexNum; j++)
if (edge[v][j] == 1 && visited[j] == 0)
DFTraverse(j);
}
// MGraph类模板的广度优先遍历函数的实现
template<typename DataType>
void MGraph<DataType>::BFTraverse(int v) {
int w, j, Q[MaxSize];
int front = -1, rear = -1;
// 先输出当前访问的起始顶点
cout << vertex[v];
// 将起始顶点标记为已访问
visited[v] = 1;
// 将起始顶点入队列
Q[++rear] = v;
// 只要队列不为空,就循环进行广度优先遍历操作
while (front!= rear) {
// 取出队头元素
w = Q[++front];
// 遍历所有顶点,查找与当前取出的顶点有边相连且未被访问的顶点
// 将这些顶点入队列,并标记为已访问,同时输出该顶点
for (j = 0; j < vertexNum; j++) {
if (edge[w][j] == 1 && visited[j] == 0) {
cout << vertex[j];
visited[j] = 1;
Q[++rear] = j;
}
}
}
}
int main() {
int i;
char ch[] = { 'A', 'B', 'C', 'D', 'E' };
// 创建一个图对象MG,传入顶点数组、顶点数量和边的数量进行初始化
MGraph<char> MG(ch, 5, 6);
// 初始化访问标记数组,用于深度优先遍历前的准备,将所有元素置为0
for (i = 0; i < MaxSize; i++)
visited[i] = 0;
cout << "深度优先遍历顺序为:";
// 对图MG从顶点0开始进行深度优先遍历
MG.DFTraverse(0);
// 再次初始化访问标记数组,用于广度优先遍历前的准备,将所有元素置为0
for (i = 0; i < MaxSize; i++)
visited[i] = 0;
cout << "广度优先遍历顺序为:";
// 对图MG从顶点0开始进行广度优先遍历
MG.BFTraverse(0);
return 0;
}