#ifndef graph_h
#define graph_h
#include<iostream>
#include<queue>
#include<stack>
#include<map>
using namespace std;
//利用邻接矩阵构造无向图,实现BFS和DFS遍历
class AMGraph{
char *vex;//存储顶点
int **arc;//邻接矩阵。 边的权值与顶点数据类型分别为int和char型
int vexNum, arcNum;//图的点数和边数
map<char, int>m; //实现顶点到坐标的映射
map<int, char>_m;//实现坐标到顶点的映射 如果顶点和权值均为Int型就不需要映射
public:
AMGraph(int _vexNum, int _arcNum);
void createUDN(); //创建无向图
void DFS(char ch);
void BFS(char ch);//从指定顶点出发遍历
};
AMGraph::AMGraph(int _vexnum, int _arcnum) :vexNum(_vexnum), arcNum(_arcnum) {
vex = new char[_vexnum];
arc = new int* [_vexnum];
for (int i = 0; i < _vexnum; ++i) {
arc[i] = new int[_vexnum];
}
}
3.构造邻接矩阵
void AMGraph::createUDN() {
char v1, v2;//一条边的两端顶点
int weight;//一条边上的权值
cout << "请输入顶点信息:" << endl;
//建立映射关系
for (int i = 0; i < vexNum; i++) {
cin >> vex[i]; //A B C D E F
/*以main函数用的例子:
A B C D E F
0 1 2 3 4 5
*/
m[vex[i]] = i; //实现A B C D E F到0 1 2 3 4 5的映射
_m[i] = vex[i]; //实现0 1 2 3 4 5到A B C D E F的映射
}
//初始化邻接矩阵,边的权值均为无穷大
for (int i = 0; i < vexNum; i++) {
for (int j = 0; j < vexNum; j++)
arc[i][j] = numeric_limits<int>::max(); //返回编译器允许的 int 型数最大值。
}
//构造邻接矩阵
cout << "请输入一条边两端顶点以及权值,空格隔开:" << endl;
for (int k = 0; k < arcNum; k++) {
cin >> v1 >> v2 >> weight;
int _i = m.at(v1);
int _j = m.at(v2);//获取两个端点在数组中的下标
arc[_i][_j] = weight;
arc[_j][_i] = weight; //设置边的权值,对称矩阵
}
}
4.DFS遍历(非递归)
void AMGraph::DFS(char ch) {
bool* visited = new bool[vexNum];
int temp;
for (int i = 0; i < vexNum; i++) //对所有结点标记为没有访问
visited[i] = false;
stack<char>s;
int start = m.at(ch); //获取坐标
s.push(start);
while (!s.empty()) {
temp = s.top();
s.pop(); //获取栈顶元素并出栈
if (!visited[temp]) {
cout << _m.at(temp); //访问
visited[temp] = true; //将该顶点标记为已访问
}
for (int i = 0; i < vexNum; i++) {
if (!visited[i]&&arc[temp][i]!= numeric_limits<int>::max()) //检查没有访问过的相邻结点
s.push(i);
}
}
delete[]visited;
}
5.BFS遍历
void AMGraph::BFS(char ch) {
bool* visited = new bool[vexNum];
int temp;
for (int i = 0; i < vexNum; i++)
visited[i] = false;
int start = m.at(ch);
queue<int>q;
q.push(start); //将起点入队
while (!q.empty()) {
temp = q.front();
q.pop();
if (!visited[temp]) {
cout << _m.at(temp); //输出坐标对应的结点值
visited[temp] = true; //标记为已访问
for (int i = 0; i < vexNum; i++) {
if (!visited[i] && arc[temp][i] != numeric_limits<int>::max()) //检查没有访问过的相邻结点,将它入队
q.push(i);
}
}
}
delete[]visited;
}
6.main函数
#include"Graph.h"
int main()
{
char ch;
int vexNum, arcNum;
cout << "请输入顶点数和边数,空格隔开:" << endl;
cin >> vexNum >> arcNum;
AMGraph* G = new AMGraph(vexNum, arcNum);
cout << "利用邻接矩阵创建无向图成功" << endl;
G->createUDN();
cout << "请输入遍历起始位置:" << endl;
cin >> ch;
cout << "深度优先遍历结果:" << endl;
G->DFS(ch);
cout << endl << "广度优先遍历结果:" << endl;
G->BFS(ch);
return 0;
}
//6 7
/*
A B C D E F
输入A作为起始遍历
A B 1
A C 3
A D 2
C E 4
D E 2
E F 1
B F 5
*/