图的邻接矩阵表示法及深度优先、广度优先遍历算法

 知识点:

1、图的邻接矩阵表示法;

2、图的深度优先遍历算法;

3、图的广度优先遍历算法。

//图的邻接矩阵表示法
//基于邻接矩阵表示法的图的遍历 
#include "string.h" 
#include<stdlib.h>
#include<queue> 
#include<iostream>
using namespace std;

struct MGraph
{
	char*  vexs[100];//存储顶点信息,0下标处不存储数据
	double arcs[100][100];//存储边的信息
	int vexnum,arcnum;//顶点数目和边的数目
};

void InitGraph(MGraph &mg)
{//图的初始化
	mg.arcnum=mg.vexnum=0;//顶点和边的数目均为0
	for(int i=0;i<100;i++)
		for(int j=0;j<100;j++)
			mg.arcs[i][j]=0;//各个顶点之间在初始情况下均没有边相连
}
//
int FindVex(MGraph mg,char *vex)
{//查找顶点vex是否存在
	for(int i=1;i<=mg.vexnum;i++)
	{//数组0下标处单元不用来存储顶点信息
		if(strcmp(mg.vexs[i],vex)==0)
			return i;//顶点存在,返回i
	}
	return 0;//顶点不存在,返回0
}

int FindArc(MGraph mg,char *v1,char *v2)
{//查找边<v1,v2>是否存在
	int x,y;
	x=FindVex(mg,v1);
	y=FindVex(mg,v2);

	if(x==0 || y==0) return 0;//某个顶点不存在,边肯定不存在,返回0
	return mg.arcs[x][y];
}
//
void InsertVex(MGraph &mg,char *vex)
{//插入一个顶点vex
	if(FindVex(mg,vex)==0)//顶点不存在
	{
		mg.vexnum++;//开辟一个空间
		mg.vexs[mg.vexnum]=new char[strlen(vex)];
		strcpy(mg.vexs[mg.vexnum],vex);//新顶点加入
	}	

}
//
void InsertArc(MGraph &mg,char *v1,char *v2)
{//插入一条边<v1,v2>
	int x,y;
	x=FindVex(mg,v1);
	y=FindVex(mg,v2);

	if(x && y)
	{
		mg.arcs[x][y]=1;
		mg.arcnum++;
	}
}

int FirstAdjVex(MGraph mg,int v)
{
	//这里用顶点的下标代替字符串,
	//如顶点“v1“对应下标为v,我们用v代表“v1“
	//在图mg中,求顶点v的第一个邻接点。
	for(int i=1;i<=mg.vexnum;i++)
	{
		if(mg.arcs[v][i]!=0)
			return i;
	}
	return 0;//不存在邻接点时,返回0
}
///
int NextAdjVex(MGraph mg,int v,int w)
{//在图mg中,求顶点v的相对于顶点w的下一个邻接点
	for(int i=w+1;i<=mg.vexnum;i++)
		if(mg.arcs[v][i]!=0)
			return i;
	return 0;
}
///
void print(MGraph mg)
{
	int i;
	for(i=1;i<=mg.vexnum;i++)
	{
		cout<<mg.vexs[i]<<" ";
	}
	cout<<endl;
	int j;
	for(i=1;i<=mg.vexnum;i++)
	{
		cout<<i<<":";
		for(j=1;j<=mg.vexnum;j++)
		{
			int k;
			k=mg.arcs[i][j];
			if(k)
				cout<<mg.vexs[j]<<" ";
		}
		cout<<endl;
	}
}
///
//深度优先遍历 
bool visited[100]={false};
void DFS(MGraph mg,int v)
{
	visited[v]=true;//以前未被访问,此处被访问
                              //改变对应的标志为已经访问
	cout<<mg.vexs[v]<<"  "; //访问结点v
	for(int w=FirstAdjVex(mg,v);w>0;w=NextAdjVex(mg,v,w))
	{//对于v的每一个邻接点进行考察
		if(visited[w]==false)//当该结点未被访问时
			DFS(mg,w);//进行深度优先遍历
	}
}
//
//广度优先遍历 
void BFS (MGraph mg,int x)
{//图的广度 优先遍历 
	bool visited[100]={false};
	queue<int> q;
	cout<<mg.vexs[x] <<"  ";visited[x]=true;
	q.push(x);
	while(q.empty()==false)
    {
		int v=q.front();
		q.pop();
		for(int w=::FirstAdjVex(mg,v);w>0;w=::NextAdjVex(mg,v,w))
		{
			if(visited[w]==false){
				cout<<mg.vexs[w]<<"  ";
				visited[w]=true;
				q.push(w);
			}
		}
	 }
}
///广度优先的递归算法
//对队列部分递归 
void BFS2RecerviePart(MGraph mg,queue<int>&q,bool *visited)
{
	if(q.empty()==false)
    {
		int v=q.front();
		q.pop();
		for(int w=::FirstAdjVex(mg,v);w>0;w=::NextAdjVex(mg,v,w))
		{
			if(visited[w]==false){
				cout<<mg.vexs[w]<<"  ";
				visited[w]=true;
				q.push(w);
			}
		}
		BFS2RecerviePart(mg,q,visited) ;
	 }
	
	
}
void BFS2(MGraph mg,int x)
{
	bool visited[100]={false};
	queue<int> q;
	cout<<mg.vexs[x] <<"  ";visited[x]=true;
	q.push(x);
	BFS2RecerviePart(mg,q,visited);
	
}
int main(int argc, char* argv[ ])
{
	MGraph mg; int i,j;
    InitGraph(mg);
	InsertVex(mg,"v1");
	InsertVex(mg,"v2");
	InsertVex(mg,"v3");
	InsertVex(mg,"v4");
	InsertVex(mg,"v5");
	InsertVex(mg,"v6");
	InsertVex(mg,"v7");
	InsertVex(mg,"v8");

	InsertArc(mg,"v1","v2");
	InsertArc(mg,"v1","v3");
	InsertArc(mg,"v2","v4");
	InsertArc(mg,"v2","v5");
	InsertArc(mg,"v3","v6");
	InsertArc(mg,"v3","v7");
	InsertArc(mg,"v4","v8");
	InsertArc(mg,"v5","v8");
	InsertArc(mg,"v6","v7");
	cout<<"打印各个顶点及其邻接点:"<<endl;
	print(mg);
	cout<<"深度优先遍历结果为:"<<endl;
	DFS(mg,1) ;
	cout<<"\n广度优先遍历结果为:"<<endl;
	BFS(mg,1);
	cout<<"\n递归的广度优先遍历结果为:"<<endl;
	BFS2(mg,1);
	
}


 

  • 3
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值