//重写一遍邻接矩阵实现图以及深度优先搜索与广度优先搜索
#include <iostream>
#include <stack>
#include <vector>
#include <queue>
#define max_vex 101 //定义结点的最大个数为max_vex
#define max_val 65534 //定义边的最大权值
using namespace std;
//重新定义数据类型
typedef int vint;
typedef char vchar;
//定义一个图的结构体
typedef struct graph{
vchar vex[max_vex]; // 存储图的顶点信息 有可能是char类型的
vint arc[max_vex][max_vex]; //存储边(连接)的权值信息
vint num_vex; //存储图当前结点的个数
vint num_arc; //存储图当前边的个数
}G;
//根据输入的值,返回其下标的函数
int find_G(G g,vchar temp){
//for循环遍历即可
for(int w=0;w<g.num_vex;++w) //不要与i重复了
{
if(g.vex[w] == temp){
return w;
}
}
return -1;
}
//创建一个图--引用方式传参
void creat_G(G &g){
//输入图中结点与边的个数
cout<<"请输入图的顶点个数num_vex和边的个数num_arc:";
cin>>g.num_vex>>g.num_arc;
//初始化边矩阵【也就是邻接矩阵的数据】
for(int i=0;i<g.num_vex;++i){
for(int j=0;j<g.num_vex;++j){
//先全部赋值为最大值
g.arc[i][j] = max_val;
}
}
//初始化结点(顶点)数据--键盘输入
cout<<endl<<"请输入结点值:"; //换行美观
for(int i=0;i<g.num_vex;++i){
cin>>g.vex[i];
}
//初始化边的权值(邻接矩阵)--键盘输入
cout<<endl<<"请输入两个节点之间的边的权值,输入样例为A B 10"<<endl;
//创建三个变量接收输入的数据
vchar vextemp1;
vchar vextemp2;
vint valtemp;
for(int i=0;i<g.num_arc;++i){
cin>>vextemp1>>vextemp2>>valtemp;
//需要将两个结点所对着的矩阵上的点置为输入的权值
int vx = find_G(g,vextemp1);
int vy = find_G(g,vextemp2);
//无向网是对称矩阵,所以直接赋值就行了
g.arc[vx][vy] = valtemp;
g.arc[vy][vx] = valtemp;
//只要值一改变就说明结束了
}
}
//将邻接矩阵打印出来
void print_G(G g){
//循环打印即可
cout<<endl<<"图G的邻接矩阵如下"<<endl<<endl;
for(int i=0;i<g.num_vex;++i){
for(int j=0;j<g.num_vex;++j){
//输出美观
if(g.arc[i][j] == max_val){
cout<<"inf"<<"\t";
}
else
{
cout<<g.arc[i][j]<<"\t";
}
}
cout<<endl;
}
cout<<endl;
}
//深度优先搜索--栈实现---按引用方式
void dfs_main(G g,int i,vector<bool> &visited,stack<int> &st){
//访问该结点
cout<<g.vex[i]<<" ";
//将该结点入栈
st.push(i); //将该结点入栈
//标记该结点已经被访问了
visited[i] = true;
while(!st.empty()) //栈内有数据,就需要一直循环
{
//获取此时栈顶的元素,对其与之相连的节点进行判断
int temp=0;
int m=0; //m的表示范围
temp = st.top(); //获取栈顶元素,但是不删除
//找到一个与之相连的结点
for(m=0;m<g.num_vex;++m){
if(g.arc[temp][m]!=max_val && visited[m]==false){
//这个就是要找的点
//将这个点入栈
st.push(m);
//访问这个数据+标记
cout<<g.vex[m]<<" "; //可以单独编写一个函数
visited[m] = true;
//找到一个结点,就先暂停,沿着这个结点再找下去
break;
}
}
if(m == g.num_vex){
//说明,与这个结点相连的结点全部访问结束了
//那么就将这个结点弹出栈
st.pop(); //删除但是不返回
}
}
}
//深度优先搜索入口函数{主要解决不连通图问题}--确保每个点都访问到
void dfs_G(G g){
cout<<endl<<"深度优先搜索:";
//创建一个辅助数组,记录当前结点是否访问过
vector<bool> visited(g.num_vex,false);
//创建一个栈,实现深度优先搜索
stack<int> st; //存储结点在数组中的下标
//开始便利实现:
for(int i=0;i<g.num_vex;++i){
//判断是否需要访问
if(!visited[i]){
//如果没有访问过,就对他执行深度优先搜索
dfs_main(g,i,visited,st);
}
}
}
//广度优先搜索--队列实现--按引用方式
void bfs_main(G g,int i,vector<bool> &visited,queue<int> &dl){
//先访问这个节点
cout<<g.vex[i]<<" ";
visited[i]= true; //标记以后以后不会再访问了
//将这个结点入队
dl.push(i);
//队列不为空就一直循环
while(!dl.empty()){
int temptop = 0; //记录队列首元素
temptop = dl.front(); //队首元素接收
//将这个结点出队
dl.pop(); //删除但是不返回
//将这个结点出队,再将他的相邻接点入队
for(int w=0;w<g.num_vex;++w){
//判断是否满足入队条件
if(visited[w]==false && g.arc[temptop][w]!=max_val){
//将所有相连接的结点入队
cout<<g.vex[w]<<" ";
dl.push(w);
visited[w] = true;
}
}
}
}
//广度优先搜索入口函数
void bfs_G(G g){
cout<<endl<<"广度优先搜索:";
//使用队列来实现
vector<bool> visited(g.num_vex,false);
queue<int> dl; //初始化一个队列
//循环解决各个定点
for(int i=0;i<g.num_vex;++i){
//判断是否需要
if(visited[i] == false){
//进行广度搜索
bfs_main(g,i,visited,dl);
}
}
}
int main(){
//定义一个结构体变量--图
G g;
creat_G(g);
print_G(g);
dfs_G(g);
bfs_G(g);
return 0;
}
12-14
393
05-29
1110
10-12
3019