图的广度搜索(C语言版)



图的广度搜索,明确是无向图,根据提示示例,分析下列代码:


  1.首先给出程序示例输入输出:


2.然后贡献详细代码

#include<stdio.h>
#include<stdlib.h>
#define MAX 100
int visited[MAX]={0};//定义一个访问标志数组 
typedef struct       //定义一个结构体代表顺序队列 
{
	int front;
	int rear;
	int data[MAX];
}Queue;
typedef struct      //定义一个结构体代表图的邻接矩阵 
{
	int vexs[MAX];
	int arcs[MAX][MAX];
	int vexnum,arcnum;
}Graph;                   
void InitQueue(Queue *q);//队列的初始化 
int EmptyQueue(Queue *q);//判断队列非空 
int DeQueue(Queue *q);//出队 
void EnQueue(Queue *q,int data);//入队 
void CreateUDN(Graph &G);//创建图的邻接矩阵 
int LocateVex(Graph G,int v);//确定顶点数组的下标 
void BFS(Graph G,int v);//图的广度搜索 
int FirstAdjVex(Graph G,int v);//选定点的第一个临接点 
int NextAdjVex(Graph G,int v,int w);//相对于第一个选定点的下一个临接点,w大于等于0代表存在临接点 
main()
{
	Graph G;//创建图G 
	CreateUDN(G);//  对图G进行初始化,以此确定图G的结构 
	int i;
	scanf("%d",&i);//输入从哪一个点进行图的广度搜索 
	BFS(G,i);//对图G进行广度搜索 
}
void InitQueue(Queue *q) 
{ 
	q->front=q->rear=0;  //初始化队列,置空 
}
int EmptyQueue(Queue *q)
{
	if(q->rear==q->front) //若队列头位置等于队列尾位置,代表队列为空 
		return 1;        
	else       
		return 0;
}
void EnQueue(Queue *q,int data)  
{  
	if((q->rear+1)%MAX==q->front)//若环形队列队满,退出 
		exit(0);
	q->data[q->rear]=data;//元素入队 
	q->rear=(q->rear+1)%MAX;//队头向前移位(这里是环形队列的创建,不多解释) 
}
int DeQueue(Queue *q)  
{  
	int data;
	if(q->front==q->rear)   //若队列为空,无法出队 
		return 0;
	data=q->data[q->front];    //队列不为空,出对尾元素,即先出先进来的元素 
	q->front=(q->front+1)%MAX;  //环形队列 对尾向前移位 
	return data;
}
void CreateUDN(Graph &G)
{
	scanf("%d%d",&G.vexnum,&G.arcnum);  //输入图的节点数和边数 
	int i,j,k;
	for(i=0;i<G.vexnum;i++){     //输入所有节点值 
		scanf("%d",&G.vexs[i]);
	}
	for(i=0;i<G.vexnum;i++)      //为图创建邻接矩阵 
	{
		for(j=0;j<G.vexnum;j++)
		{
			G.arcs[i][j]=0;     //初始化邻接矩阵为0 
		}
	}
	for(k=0;k<G.arcnum;k++)
	{
		int v1,v2,w;
		scanf("%d%d%d",&v1,&v2,&w);   //输入边的起始点和终点,并赋权值 
		i=LocateVex(G,v1);            //确定起始点在邻接矩阵中的下标表示 
		j=LocateVex(G,v2);            //确定终点在邻接矩阵中的下标表示 
		G.arcs[i][j]=w;
		G.arcs[j][i]=G.arcs[i][j];    //无向图对称 
	}
}
int LocateVex(Graph G,int v)      //确定某点在邻接矩阵中下标的具体方法 
{
	int i=0;
	while ((v!=G.vexs[i])&&(i<G.vexnum)) 
		i++;
	return i;
} 
void BFS(Graph G,int v)
{
	printf("%d",v);      //首先输出起始遍历的点 
	visited[v]=1;        //对起始点进行标记,表示已经访问过v点,以后不用再次访问 
	int w;
	int u;
	Queue Q;             //创建队列Q,用来对已访问点做标记 
	InitQueue(&Q);       //初始化队列 
	EnQueue(&Q,v);       //元素v入队 
	while(!EmptyQueue(&Q))   //队列不为空,执行while循环 
	{
		u=DeQueue(&Q);       //元素出队 
		for(w=FirstAdjVex(G,u);w>=0;w=NextAdjVex(G,u,w))//依次检查u的所有临接点(按程序往下看,可以读懂,不多解释) 
		{
			if(!visited[w]) //若没有访问过此点,即此点数组值为0,进行打印输出 
			{
				printf("%d",w);      //打印第一次访问的点 
				visited[w]=1;        //对访问的这个点做标记,对数组值赋一,表示已经遍历此点 
				EnQueue(&Q,w);       //将访问的此点入队 ,进入下次循环,找此点另外没有访问过的临接点 
			}
		}
	}
}
int FirstAdjVex(Graph G,int v)        //自己按示例数据分析此方法,不多解释 
{
	int i=0;
	while((i<G.vexnum)&&(G.arcs[v][i]==0)) 
		i++;
	if (i==G.vexnum) 
		return -1;
	else 
		return i;
}
int NextAdjVex(Graph G,int v,int w)    
{
	int i=0;
	for(i=w+1;(i<G.vexnum)&&((G.arcs[v][i]==0));i++)   //这里循环找临接点,循环内部不需要执行任何代码,和上边找第一个点中的while类似 
	{}
	if (i==G.vexnum) 
		return -1;
	else 
		return i;
}



  • 1
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
广度优先搜索(BFS)是一种用于解决或树的遍历问题的算法,八数码问题的解决也可以使用广度搜索算法。八数码问题是一个9个数字的滑块拼游戏,目标是通过移动滑块来将乱序排列的数字按照从小到大的顺序排列。 在C语言中,可以使用队列来实现广度搜索算法。首先,我们需要定义一个表示每个状态的数据结构,包括一个3x3的矩阵来表示滑块的当前排列,以及一个指向父状态的指针。然后,我们定义一个队列,用于保存待搜索的状态。 算法的步骤如下: 1. 创建一个队列,并将初始状态加入队列中。 2. 从队列中取出一个状态,判断是否为目标状态。如果是,说明已找到解决方案,结束搜索。 3. 如果不是目标状态,生成当前状态的所有可能的下一步状态,并将它们加入队列中。 4. 重复步骤2和3,直到找到目标状态或队列为空。 在生成下一步状态时,我们需要注意一些限制条件。例如,滑块只能上、下、左、右移动,且不能越界。此外,为了避免重复搜索同一个状态,我们需要记录已经搜索过的状态,可以使用一个哈希表来保存已访问过的状态。 当找到目标状态时,我们可以通过回溯父状态指针来获取解决方案的具体步骤。 总而言之,通过使用队列和哈希表来实现广度搜索算法,可以有效地解决八数码问题。该算法可以生成最少移动步数的解决方案,并且不会陷入死循环。通过合理的编程实现,可以帮助我们更好地理解和解决八数码问题。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值