BFS解决迷宫问题 C


2.利用BFS查找最短路径
//队列应用_迷宫问题
#include<stdio.h>
//内存分配函数需加载的头文件
#include<stdlib.h>
//宏定义迷宫的行数
#define M 5
//宏定义迷宫的列数
#define N 5
//定义方格的结构体类型
typedef struct
{
    //方格的行标
    int row;
    //方格的列标
    int column;
    //步长
    int pathLen;
    //当前方格的父亲方格的行标
    int parentRow;
    //当前方格的父亲方格的列标
    int parentColumn;
}box;
//方向结构类型
typedef struct
{
    //行标变化量
    int drow;
    //列标变化量
    int dcolumn;
}direction;
//定义队列结构体
typedef struct
{
    //数据域
    box  *data;
    //队头 队尾游标
    int tail,head;
    //队列容量
    int size;
}Queue;
//队列初始化
void initQ(Queue &Q,int n)
{
    //为队列分配存储空间 有一块空间用以判断队列是否已满弃用了 故多分配一个存储空间
    Q.data=(box *)malloc(sizeof(box)*(n+1));
    //将队列置为空队
    Q.head=Q.tail=0;
    //设置队列容量
    Q.size=n;
}
//入队
void in(Queue &Q,box b)
{
    //判断队列是否已满
    if((Q.tail+1)%Q.size!=Q.head)
    {
        //队列未满,元素b入队
        Q.data[Q.tail]=b;
        //队尾游标后移
        Q.tail=(Q.tail+1)%Q.size;
    }
}
//出队
box out(Queue &Q)
{
    //判断队列是否已空
    if(Q.head!=Q.tail)
    {
        //队列未空 赞存队首元素
        box e;
        e=Q.data[Q.head];
        //队首游标后移
        Q.head=(Q.head+1)%Q.size;
        return e;
    }
}
//定义方向数组
direction directions[4]={
        {0,1},//向右移动,行标不变 列标+1
        {1,0},//向下移动,行标+1 列标不变
        {0,-1},//向左移动,行标不变 列标-1
        {-1,0} //向上移动 行标-1 列标不变
};
//迷宫数组
int maze[M][N];
//判断方格是否合法  方格的行标 列标是否在迷宫范围内? 方格是否可通行?
int isValid(box b)
{
    return (b.row>=0&&b.row<M&&b.column>=0&&b.column<N&&maze[b.row][b.column]==0);
    /* maze[b.row][b.column]!=0 两种情形
     *  1.b为墙体不可通行
     *  2.b已访问过
     * */
}
void printPath(box b)
{
    //打印的最短路径为为终点到起点  逆序 若想打印正序  依次放入一个栈中,然后出栈打印
    while(b.row!=-1&&b.column!=-1)
    {
        printf("row:%-2d,column:%-2d\n",b.row,b.column);
        //更新方格的行标 列标
            b.row=b.parengRow;
           b.column=b.parentColumn; 
    }
}
//计算最短路径长度
int getMinPath(box b,Queue &Q)
{
    //将起点方格入队
    in(Q,b);
    //将起点方格修改为已访问
    maze[b.row][b.column]=-1;
    //当队列未空时,取队首元素
    while(Q.head!=Q.tail)
    {
        //取队首元素 next 下一个方格
        box current,next;
        current= out(Q);
        //判断是否到大重点 若此时到达重点,则current.pathLen就是最小路径长度
        if(current.row==M-1&&current.column==N-1)
        {
            //打印最短路径
            printPath(current);
            return current.pathLen;
        }
        //当前方格尝试不同的方向 向外扩展
        int di;
        di=0;
        while(di<4)
        {
            //计算下一个方格的行标 列标
            next.row=current.row+directions[di].drow;
            next.column=current.column+directions[di].dcolumn;
            //每次向外扩展步长均扩大1
            next.pathLen=current.pathLen+1;
            //设置下一个方格的 父亲方格的行标 列标
            next.parentRow=current.row;
            next.parentColumn=current.column;
            //判断下一个方格的合法性
            if(isValid(next))
            {
                //将下一个方格标记为已访问
                maze[next.row][next.column]=-1;
                //将下一个方格入队
                in(Q,next);
            }
                //尝试其他方向
                di++;
        }
    }
    //当队列空时,仍未到达终点 则不存在最短路径
    return -1;
}

void getLen(int n)
{
    Queue Q;
    //初始化队列
    initQ(Q,n);
    //设置当前方格
    box  b;
    b.row=b.column=b.pathLen=0;
    //起点方格 的父亲方格行标 父亲方格列标均为-1
    b.parentRow=b.parentColumn=-1;
    printf("%-2d", getMinPath(b,Q));
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值