数据结构和C++小白的第一篇文章,记录一下自己学习过程中遇到的问题!...(* ̄0 ̄)ノ
前言
这几天学了栈和队列,正所谓在实践中检验真理,我们这种小白当然得多敲代码才能成为我们身边的那些大佬,的跟班。
回到正文,其实是使用队列进行广度优先遍历进行寻路时遇到了一个小问题,就是找到出口后该如何把最优路径和所有走过的路区别出来呢(⊙o⊙)?
一、思路
队列寻路的思路我的理解就是创建一个队列存放位置(二维地图数组的下标),从入口入队开始,封装一个返回值为布尔型的函数去寻找周围的路。
函数中当前点出队,然后判断这个点的上下左右四个方向是否有空地,有就入队(这里需要注意数组越界的情况,并且队列和点的位置记得传引用或指针),走到一个点就将其给一个固定的值,表明这个点已经走过了,不再把它当成空地,如果这四个方向中有出口点,那么返回true,否则函数执行完后返回false。
用一个变量如s去接收这个值。这样我们就可以写一个while循环,条件是!s,即s为true时结束循环,循环体就把此函数赋值给s即可。
二、最优路径
所以我们理解了上述步骤后,就进入正题——找到出口后如何显示那条最优路径。
我们其实可以通过计数来解决这个问题。这个步骤可以放到上面提到的那个函数中实现,不用某个固定的值去表明某个点已经走过。将起始点的值改变一下,让它的值后面不要有出口或墙这些元素,在四个方向中的某个入队时,给一个值比当前点的值多1,直到循环找到出口时,此时的坐标表示应该是出口的上一个点。
创建一个栈存放位置(二维地图数组的下标),从那个点入栈开始,判断它的上下左右四个方向,找到值比它小一的点,然后将位置改到这个点,直到当前点的位置回到起始点(入口)。这个步骤也需封装成函数放入循环中执行。最后得到的栈存放的就是最优路径了,我们将其渲染出来即可。
三、代码
#include <iostream>
#include <vector>
#include <stack>
#include <queue>
#include <windows.h>
using namespace std;
/*
利用队列搜索路径
*/
//色彩函数的声明
void COLOR(const char* s, int color);
//用二维数组创建一个地图
int GameMap[10][10] = {
{ 1, 10, 1, 1, 1, 1, 1, 1, 1, 1 },
{ 1, 0, 0, 0, 1, 1, 1, 1, 0, 1 },
{ 1, 0, 1, 0, 0, 0, 0, 0, 0, 1 },
{ 1, 0, 0, 1, 0, 1, 0, 1, 1, 1 },
{ 1, 0, 1, 1, 1, 1, 0, 0, 0, 1 },
{ 1, 0, 1, 1, 0, 1, 0, 1, 4, 1 },
{ 1, 0, 0, 0, 0, 1, 0, 1, 0, 1 },
{ 1, 0, 1, 0, 1, 1, 0, 1, 0, 1 },
{ 1, 0, 1, 0, 0, 0, 0, 0, 0, 1 },
{ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
};
//渲染地图
void RenderMap(int GameMap[10][10])
{
for (int i = 0; i < 10; i++)
{
for (int j = 0; j < 10; j++)
{
switch (GameMap[i][j])
{
case 0:
cout << " ";
break;
case 1:
COLOR("■", 4);
break;
case 2:
COLOR("♀",1);
break;
case 10:
cout << "入";
break;
case 4:
cout << "出";
break;
default:
cout << "♀";
break;
}
}
cout << endl;
}
}
//位置结构体的定义
struct Pos
{
int x;
int y;
};
//1.显示搜索的整个过程;
bool FindRoad1(int GameMap[10][10], Pos &MyPos, queue<Pos> &s)
{
MyPos = s.front();
s.pop();
if (MyPos.x - 1 >= 0 && MyPos.x - 1 <= 9 && (0 == GameMap[MyPos.x - 1][MyPos.y] || 4 == GameMap[MyPos.x - 1][MyPos.y]))//上
{
Pos NewPos = { MyPos.x - 1, MyPos.y };
s.push(NewPos);
if (4 == GameMap[MyPos.x - 1][MyPos.y])
return true;
GameMap[MyPos.x - 1][MyPos.y] = GameMap[MyPos.x][MyPos.y]+1;
}
if (MyPos.x + 1 >= 0 && MyPos.x + 1 <= 9 && (0 == GameMap[MyPos.x + 1][MyPos.y] || 4 == GameMap[MyPos.x + 1][MyPos.y]))//下
{
Pos NewPos = { MyPos.x + 1, MyPos.y };
s.push(NewPos);
if (4 == GameMap[MyPos.x + 1][MyPos.y])
return true;
GameMap[MyPos.x + 1][MyPos.y] = GameMap[MyPos.x][MyPos.y]+1;
}
if (MyPos.y - 1 >= 0 && MyPos.y - 1 <= 9 && (0 == GameMap[MyPos.x][MyPos.y - 1] || 4 == GameMap[MyPos.x][MyPos.y - 1]))//左
{
Pos NewPos = { MyPos.x, MyPos.y - 1 };
s.push(NewPos);
if (4 == GameMap[MyPos.x][MyPos.y - 1])
return true;
GameMap[MyPos.x][MyPos.y - 1] = GameMap[MyPos.x][MyPos.y]+1;
}
if (MyPos.y + 1 >= 0 && MyPos.y + 1 <= 9 && (0 == GameMap[MyPos.x][MyPos.y + 1] || 4 == GameMap[MyPos.x][MyPos.y + 1]))//右
{
Pos NewPos = { MyPos.x, MyPos.y + 1 };
s.push(NewPos);
if (4 == GameMap[MyPos.x][MyPos.y + 1])
return true;
GameMap[MyPos.x][MyPos.y + 1] = GameMap[MyPos.x][MyPos.y]+1;
}
return false;
}
//寻找最优路径
void FindFast(stack<Pos>& s1, Pos& MyPos)
{
s1.push(MyPos);
if (MyPos.x - 1 >= 0 && MyPos.x - 1 <= 9 &&
GameMap[MyPos.x][MyPos.y]-1 == GameMap[MyPos.x - 1][MyPos.y])
MyPos.x --;
else if (MyPos.x + 1 >= 0 && MyPos.x + 1 <= 9 &&
GameMap[MyPos.x][MyPos.y] - 1 == GameMap[MyPos.x + 1][MyPos.y])
MyPos.x--;
else if (MyPos.y - 1 >= 0 && MyPos.y - 1 <= 9 &&
GameMap[MyPos.x][MyPos.y] - 1 == GameMap[MyPos.x][MyPos.y - 1])
MyPos.y--;
else if (MyPos.y + 1 >= 0 && MyPos.y + 1 <= 9 &&
GameMap[MyPos.x][MyPos.y] - 1 == GameMap[MyPos.x][MyPos.y + 1])
MyPos.y++;
}
int main()
{
RenderMap(GameMap);
//创建存放位置的队列
queue<Pos> s;
Pos MyPos = { 0, 1 };
s.push(MyPos);
bool isfind = false;
//循环找到出口
while (!isfind)
{
isfind = FindRoad1(GameMap, MyPos, s);
system("CLS");
RenderMap(GameMap);
Sleep(200);
}
//创建存放位置的栈
stack<Pos> s1;
//循环找最优路径
while (10 != GameMap[MyPos.x][MyPos.y])
{
FindFast(s1, MyPos);
}
//渲染出最优路径
while (!s1.empty())
{
GameMap[s1.top().x][s1.top().y] = 2;
s1.pop();
system("CLS");
RenderMap(GameMap);
Sleep(200);
}
cout << "蓝色路径即为为最短路径!" << endl;
return 0;
}
//色彩函数
void COLOR(const char* s, int color)
{
HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleTextAttribute(handle, FOREGROUND_INTENSITY | color);
printf(s);
SetConsoleTextAttribute(handle, FOREGROUND_INTENSITY | 7);
}
四、结果图
总结
第一次写文章还有很多不足,表达描述肯定也有很多不清楚的地方,以后我会多多锻炼,如果有什么错误或者问题还请大佬们指出哈!