其他相关文章
使用栈数据结构进行全排序
数据结构 - 广度搜索 -迷宫问题
数据结构- 炸弹人游戏
数据结构 - 树 堆
任务目标:对于迷宫问题,使用队列找到最小路径
广度搜索算法流程:
- 放入出发点作为队列头
- 循环(如果列表为空则退出)
3. 找队列头的下一步点,将所有可能的下一步点放入队列(排除:超边界、走过的路)
4. 如果某个点等于终点结束大循环
5. 当那个点的下一步点全部入队列后,删除那个点
深度搜索算法流程(循环法):
3. 放入出发点作为头;包括(建立栈、路径变量)
4. 循环的方式获得一个邻居;
5. 有邻居则邻居入栈,修改路径;无邻居则弹出自己,同时进行实际操作
深度搜索算法流程(嵌套法)(树):
- 判断嵌套是否结束(最好是依据自己,不是下一个);
- 实际操作()
注意:
3. 实际操作放在一起,防止乱;
4. 行列用新变量表示
5. 即时删除 pop,容易忘记;
代码
// 使用广度搜索解决迷宫问题,并回溯打印路径
// [link](https://blog.youkuaiyun.com/k346k346/article/details/51289478)
#include <iostream>
#include <queue>
#include<vector>
using namespace std;
struct Point {
//行与列
int row;
int col;
int step = 0;
//默认构造函数
Point() {
row = col = -1;
}
Point(int x, int y, int step_ = 0) {
this->row = x;
this->col = y;
step = step_;
}
bool operator==(const Point& rhs) const {
if (this->row == rhs.row && this->col == rhs.col)
return true;
return false;
}
};
void mazePath(queue<Point>& q, Point& target_pos);
int neighbour[4][2] = {
{1,0},
{0,1},
{-1,0},
{0,-1}
};
int maze[5][5] = {
{0, 0, 0, 0,0},
{0,-1, 0,-1,0},
{0,-1,-1, 0,0},
{0,-1,-1, 0,-1},
{0, 0, 0, 0, 0}
};
int main()
{
//
queue<Point> vecPath;
vecPath.push(Point(0, 0));
maze[0][0] = 1;
Point endpoint = Point(4, 4);
mazePath(vecPath, endpoint);
}
bool valid_point(Point point) {
//判断点是否可以作为下一 1 障碍物 2 边界 3 未走过
int row = sizeof(maze) / sizeof(maze[0]);
int col = sizeof(maze[0]) / sizeof(maze[0][0]);
if (maze[point.row][point.col] == -1) {
return false;
}
if ((point.row < 0 || point.row > row - 1) || (point.col < 0 || point.col > col - 1))
return false;
else
if (maze[point.row][point.col] == 0)
return true;
else {
cout << "wrong in valid" << endl;
return false;
}
}
void mazePath(queue<Point>& q, Point& target_pos) {
int flag = 0;
int row = sizeof(maze) / sizeof(maze[0]);
int col = sizeof(maze[0]) / sizeof(maze[0][0]);
Point temp_point, new_point;
int i = 1;
// 建立一个二维数组,每个数组里面是Point
Point** mark = new Point * [row];//[TODO] 这里不需要释放吗?
//for (auto ) // ?auto 吗?[TODO]
for (int i = 0; i < row; i++) {
mark[i] = new Point[col];
}
// 开始的格子指向自己
mark[0][0] = Point(0, 0);
// 指向数组的指针
int* a;
while (q.empty() == false) {
// 取
temp_point = q.front();
// 获取相邻值
for (auto deta : neighbour) {
new_point = Point(temp_point.row + deta[0], temp_point.col + deta[1], temp_point.step+1);
if (valid_point(new_point)) { // 如果点可以加入
maze[new_point.row][new_point.col] = temp_point.step +1;
mark[new_point.row][new_point.col] = temp_point;// 放入父节点
q.push(new_point);
}
if (new_point == target_pos) {
flag = 1;
break;
}
}
q.pop();
if (flag == 1) break;
i++;
}
if (q.empty() == false) {
// 获取最后一个格子的数值
temp_point = q.back();
// 依据最后一个获取前一个
while ((temp_point.row == 0 && temp_point.col == 0) == false) {
cout << " <" << temp_point.row << "," << temp_point.col << "> ";
temp_point = mark[temp_point.row][temp_point.col];
}
}
return;
}
难点:
- 其实广度遍历没什么,但是如何打印路径有点编程能力。
答:这里采用二维矩阵记录父节点的方法。建立一个Point 类型的矩阵,每个值表示其父节点(当然可能有多个,但这里只考虑了一个父节点,不影响的)。 - 如何自定义一个自设计类型的矩阵。
答:重指针+组长数组指针+类型指针
解答:
2. 自定义一个自设计类型的矩阵
A. 我们要创建的是指针的数组,确实可以有这样的东西如下代码,
Shape *s[3];//要求创建对象的指针数组,可以这样创建
s[0] = &c;//后续再相应赋值
s[1] = &sq;//此处c、sq、rt是Shape的子类对象
s[2] = &rt;
B. 所以等号右边应该是Shape *s[3] 这样的,左边就是简单的指针的指针 Shape **a
C. 但是new好像不同:指针 = new 数据类型[常量表达式]就是: Int *p = new int[10] 作为右值是没有变量名称的
D. 所以是
i. Shape xx a = new Shape[m]
E.但这个重指针指向的是组长指针,所以改为
Shape **a = new Shape* [m]
这个应该是m行,然后遍历他,给每个单个指针进行赋值。
到此,就可以用双下标的方法访问了!