广度优先搜索(BFS)寻找最短路径

#include<iostream>
using namespace std;

void EnQueue(int i, int j, int k); //入队一个节点
void DeQueue(int* i, int* j, int* k); //获取当前节点的序号和对应的迷宫坐标,然后出列
int GetNextPos(int* i, int* j, int count); //得到下一个邻接点的位置
void ShortestPath_BFS(int i, int j); //广度优先遍历寻找最短路径
void ShortestPath(); //输出最短路径
void Print(); //输出迷宫形状

int Map[10][10] = { {1,1,1,1,1,1,1,1,1,1},{1,0,0,1,0,0,0,1,0,1},{1,0,0,1,0,0,0,1,0,1},{1,0,0,0,0,1,1,0,0,1}, {1,0,1,1,1,0,0,0,0,1},
{1,0,0,0,1,0,0,0,0,1},{1,0,1,0,0,0,1,0,0,1},{1,0,1,1,1,0,1,1,0,1},{1,1,0,0,0,0,0,0,0,0},{1,1,1,1,1,1,1,1,1,1} };
int front = 0, rear = 0; //队列头指针和尾指针

struct Node
{
	int parent_id; //保存父节点的位置
	int node_id; //当前节点的序号,以便传递给孩子节点
	int x, y; //当前结点对应的坐标
}Q[10 * 10]; //每个节点包含迷宫坐标、队列中的序号、父节点的序号,多个节点形成队列



int main()
{
	cout << "程序说明:" << '\n' << "1.输出路径为最短路径;" << '\n' << "2.默认的出口在最右下角,如有需要可以调整。" << '\n' << '\n';
	cout << "初始地图如下:" << endl;
	Print();
	int i, j;//起点x y坐标

reinput: cout << "请输入起点坐标(x,y): " << endl; cin >> i >> j;

	if (Map[i][j])
	{
		cout << "不能从该处出发,请重新输入!" << endl; goto reinput;
	}
	ShortestPath_BFS(i, j); cout << "最短路径之一如下:" << endl;
	ShortestPath();
}

void EnQueue(int i, int j, int k) //入队一个节点
{
	Q[rear].x = i;
	Q[rear].y = j; //保存当前节点对应的坐标位置
	Q[rear].parent_id = k; //保存父节点的序号 
	Q[rear].node_id = rear; //保存当前节点序号
	rear++;
}

void DeQueue(int* i, int* j, int* k) //获取当前节点的序号和对应的迷宫坐标,然后出列
{
	*i = Q[front].x;
	*j = Q[front].y;
	*k = Q[front].node_id;
	front++; //出列一个节点
}

int GetNextPos(int* i, int* j, int count) //得到下一个邻接点的位置
{
	switch (count)
	{
	case 1:(*j)++; return 1; //右
	case 2:(*i)++; return 1; //下
	case 3:(*j)--; return 1; //左
	case 4:(*i)--; return 1; //上
	default:
		return 0;
	}
}

void ShortestPath_BFS(int i, int j) //广度优先遍历寻找最短路径 i j为起点的坐标
{
	int count, m, n, k;
	EnQueue(i, j, -1);
	Map[i][j] = 1; //起点入队,标记起点已走过
	while (true)
	{
		count = 1;
		DeQueue(&i, &j, &k);//父结点出列 将父结点作为新的起点开始下一层的搜索
		n = i, m = j;
		//保存当前位置
		while (GetNextPos(&i, &j, count))
		{
			count++;//利用count依次把四个方向都尝试一遍
			if (!Map[i][j])//如果该结点还没有走过,则将其入列并标记为走过  //如何确保不会越界??? 
			{
				EnQueue(i, j, k);
				Map[i][j] = 1;
				if (i == 8 && j == 9)
					return; //经过最少步到达终点就是最短路径,返回
			}
			i = n; j = m; //保证遍历当前坐标的所有相邻位置
		}
	}

}



void ShortestPath()
{
	int i, j, k, sum = 0;
	k = rear - 1;
	while (k != -1)
	{
		i = Q[k].x;
		j = Q[k].y;
		Map[i][j] = 2;
		k = Q[k].parent_id;
	}
	cout << " 0 1 2 3 4 5 6 7 8 9" << endl;

	for (i = 0; i < 10; i++)
	{
		cout << i;
		for (j = 0; j < 10; j++)
		{
			if (Map[i][j] == 2)
			{
				sum++; cout << "□";
			}
			else
				cout << "■";
		}
		cout << endl;
	}

	cout << "最短路径长度:" << sum << endl;
}

void Print()
{
	cout << " 0 1 2 3 4 5 6 7 8 9" << endl;
	for (int i = 0; i < 10; i++)
	{
		cout << i;
		for (int j = 0; j < 10; j++)
		{
			if (Map[i][j])
				cout << "■";
			else
				cout << "□";
		}
		cout << endl;
	}
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值