队列应用之 bfs(广度优先搜索)

关于bfs广度优先搜索,移步:

这里讲述队列的应用,使用 bfs (广度优先搜索)

例1.寻找最近相同字母位置

 想法思路: 先将黄色的X进入队列,然后向左一步,向右一步分开扩展,直至找到最近的相同字母。

注意:同一个位置不能重复进入队列,,需要用数组 flag 标记进入队列的下标,避免重复进入

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define maxn 100
typedef struct node
{
    int front,rear=-1;
    char data[maxn];
    int id[maxn];
    int count;
}Squeue;
int n,flag[1001];
char ch[1001];
void init(Squeue &s)    {s.count=0; s.front=0; s.rear=-1;} //初始化
void push(Squeue &s,int x)  // 入队列
{
    s.count++;
    s.data[++s.rear]=ch[x];
    s.id[s.rear]=x; // 在原字符串中的位置
}
char pop(Squeue &s) // 出队列
{
    s.count--;
    return s.data[s.front++];
}
char getpop(Squeue &s) {return s.data[s.front];} // 返回队首
int getpopid(Squeue &s) {return s.id[s.front];} // 返回队首
bool empty(Squeue s) {if(s.front==s.rear && s.count==0) return true; else return false;} // 判断队列是否为空
void bfs(Squeue &s)
{
    if(empty(s)) return ;
    push(s,n); flag[n]=1; // 入队列 标记为已入队列
    while(!empty(s)) // 如果找不到,则在为空时,返回空
    {
        int x=getpopid(s);
        pop(s);     // 取出
        if(ch[x-1]==ch[n])  // 左边一个判断
        {
            printf("%d",x-1);
            return ;
        }
        if(ch[x+1]==ch[n]) // 右边一个判断
        {
            printf("%d",x+1);// 判断到最近的即可直接输出返回
            return ;
        }
        if(flag[x-1]==0)    {push(s,ch[x-1]); flag[x-1]=1;} // 左右如果没进入队列过,分别进入队列
        if(flag[x+1]==0)    {push(s,ch[x+1]); flag[x+1]=1;}
    }
}
int main()
{
    Squeue S;
    scanf("%s",ch); scanf("%d",&n);
    init(S);
    bfs(S);
    system("pause");
    return 0;
}

上面的例题为一维,扩展到二维

例题2. 

如同一维数组向左向右扩展一样,这里分别向上,向下,向左,向右扩展(同上面一样,同一个位置不能重复进入队列),这里由于是二维,所以各需要横纵坐标记录位置。

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<iostream>
using namespace std;
#define maxn 100
typedef struct node
{
    int front,rear=-1;
    char data[101];
    int id1[maxn]; // 二维横坐标
    int id2[maxn];// 纵坐标
    int count;
}Squeue;
char ansc;
int ans=100001;
int n,flag[101][101],m;
char ch[101][101];
void init(Squeue &s)    {s.count=0; s.front=0; s.rear=-1;}
void push(Squeue &s,int x,int y)  
{
    s.count++;
    s.data[++s.rear]=ch[x][y];
    s.id1[s.rear]=x; 
    s.id2[s.rear]=y;
}
char pop(Squeue &s) 
{
    s.count--;
    return s.data[s.front++];
}
char getpop(Squeue &s) {return s.data[s.front];} 
int getpopid1(Squeue &s) {return s.id1[s.front];} 
int getpopid2(Squeue &s) {return s.id2[s.front];} 
bool empty(Squeue s) {if(s.front>s.rear) return true; else return false;}
void bfs(Squeue &s,int x,int y)
{
    push(s,x,y); flag[x][y]=1;
    while(!empty(s))
    {
        int x1=getpopid1(s);
        int y1=getpopid2(s);
        pop(s);
        if(ch[x1+1][y1]==ch[x][y] && x1+1<=n && !(x1+1==x && y1==y))  //向右扩展,注意不能超出边界
        {
            if(ans>(abs(x1+1-x)+abs(y1-y)))
            {
            	ans=abs(x1+1-x)+abs(y1-y);
            	ansc=ch[x][y];
			}
        }
        if(ch[x1][y1+1]==ch[x][y] && y1+1<=m && !(x1==x && y1+1==y)) // 向下扩展,不能超出边界
        {
            if(ans>(abs(x1-x)+abs(y1+1-y)))
            {
            	ans=abs(x1-x)+abs(y1+1-y);
            	ansc=ch[x][y];
			}
        }
        if(ch[x1-1][y1]==ch[x][y] && x1-1>=1  && !(x1-1==x && y1==y)) // 向上扩展,不能超出边界
        {
            if(ans>(abs(x1-1-x)+abs(y1-y)))
            {
            	ans=abs(x1-1-x)+abs(y1-y);
            	ansc=ch[x][y];
			}
        }
        if(ch[x1][y1-1]==ch[x][y] && y1-1>=1  && !(x1==x && y1-1==y))// 向左扩展,不能超出边界
        {
            if(ans>(abs(x1-x)+abs(y1-1-y)))
            {
            	ans=abs(x1-x)+abs(y1-1-y);
            	ansc=ch[x][y];
			}
        }
        // 注意无论是怎么扩展,一定不能是原来的点
        if(flag[x1-1][y1]==0 && x1-1>=1 && y1>=1)    {push(s,x1-1,y1); flag[x1-1][y1]=1;}
        if(flag[x1+1][y1]==0 && x1+1<=n && y1>=1)    {push(s,x1+1,y1); flag[x1+1][y1]=1;}
        if(flag[x1][y1+1]==0 && y1+1<=m && x1>=1)   	{ push(s,x1,y1+1);flag[x1][y1+1]=1;}
        if(flag[x1][y1-1]==0 && y1-1>=1 && x1>=1) 	{push(s,x1,y1-1); flag[x1][y1-1]=1;}
    } // 没有入队列的入队列
}
int main()
{
    Squeue S;
    memset(S.id1,0,sizeof(S.id1));
    memset(S.id2,0,sizeof(S.id2));
    scanf("%d%d",&n,&m); 
    for(int i=1;i<=n;i++)
    for(int j=1;j<=m;j++)
    {
    	cin>>ch[i][j];
	}
	for(int i=1;i<=n;i++)
	for(int j=1;j<=m;j++)
	{
		init(S);
		bfs(S,i,j);
		memset(flag,0,sizeof(flag));
	}
	printf("%c",ansc);
    system("pause");
    return 0;
}

 如果熟练的采用 bfs(广度优先搜索)的话,可以直接用bfs搜索的方法

#include<stdio.h>
#include<iostream>
using namespace std;
#include<string.h>
#include<math.h>
char ch[101][101];
int n,m;
int flag[1001][1001];
int ans=100001;
char ansc;
void bfs(int x1,int y1,int x,int y) 
{
	if(flag[x1][y1]==1) return ; // 经历过的点,直接返回
	flag[x1][y1]=1;
	if(ch[x1][y1]==ch[x][y] && !(x1==x && y1==y) )
	{
		if(ans>abs(x1-x)+abs(y1-y)) 
		{
			ans=abs(x1-x)+abs(y1-y);
			ansc=ch[x][y];
		}
	}
	if(x1+1<=n && flag[x1+1][y1]==0) bfs(x1+1,y1,x,y);  // 均不能超出边界
	if(x1-1>=1 && flag[x1-1][y1]==0) bfs(x1-1,y1,x,y);
	if(y1+1<=m && flag[x1][y1+1]==0) bfs(x1,y1+1,x,y);
	if(y1-1>=1 && flag[x1][y1-1]==0) bfs(x1,y1-1,x,y); 
}
int main()
{
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++)
	for(int j=1;j<=m;j++) cin>>ch[i][j];
	for(int i=1;i<=n;i++)
	for(int j=1;j<=m;j++)
	{
		bfs(i,j,i,j);
		memset(flag,0,sizeof(flag));
	}
	printf("%c",ansc);
 } 

  • 10
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
BFS广度优先搜索算法(Breadth-First Search)是一种图的搜索算法,也是最简便的图搜索算法之一。它的目的是系统地展开并检查图中的所有节点,以找寻结果。这个算法不考虑结果的可能位置,而是彻底地搜索整张图,直到找到结果为止。广度优先搜索算法通常用于找出两个节点之间的最短路径。它可以帮助我们解决类似于寻找最短路径的问题。 BFS算法的基本思想是从起始节点开始,逐层地向外扩展,先访问离起始节点最近的节点,再逐渐向外层节点扩展,直到达到目标节点。它使用队列来存储待访问的节点,先进先出(FIFO)的特点保证了广度优先。通过不断地将节点加入队列并访问,直到队列为空,我们可以遍历整张图并找到最短路径。 BFS广度优先搜索算法的运行时间为O(V+E),其中V为顶点数,E为边数。它可以指出是否存在从起始节点到目标节点的路径,并且可以找到最短路径。当面临需要寻找最短路径的问题时,我们可以使用图来建立模型,并使用广度优先搜索算法解决问题。 参考资料: https://www.cnblogs.com/tianqizhi/p/9914539.html 文中引用的参考资料<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [代码 基于BFS广度优先搜索算法代码](https://download.csdn.net/download/s13166803785/85545057)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] - *2* *3* [广度优先搜索算法(BFS)详解](https://blog.csdn.net/lemonxiaoxiao/article/details/105730735)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值