图—深度优先搜索&广度优先搜索

//重写一遍邻接矩阵实现图以及深度优先搜索与广度优先搜索 
#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;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

hskwcy

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值