数据结构 - 广度搜索 -迷宫问题

其他相关文章

使用栈数据结构进行全排序
数据结构 - 广度搜索 -迷宫问题
数据结构- 炸弹人游戏
数据结构 - 树 堆

任务目标:对于迷宫问题,使用队列找到最小路径

广度搜索算法流程

  1. 放入出发点作为队列头
  2. 循环(如果列表为空则退出)
    3. 找队列头的下一步点,将所有可能的下一步点放入队列(排除:超边界、走过的路)
    4. 如果某个点等于终点结束大循环
    5. 当那个点的下一步点全部入队列后,删除那个点

深度搜索算法流程(循环法)
3. 放入出发点作为头;包括(建立栈、路径变量)
4. 循环的方式获得一个邻居;
5. 有邻居则邻居入栈,修改路径;无邻居则弹出自己,同时进行实际操作

深度搜索算法流程(嵌套法)(树)

  1. 判断嵌套是否结束(最好是依据自己,不是下一个);
  2. 实际操作()

注意:
3. 实际操作放在一起,防止乱;
4. 行列用新变量表示
5. 即时删除 pop,容易忘记;
代码

// 使用广度搜索解决迷宫问题,并回溯打印路径
// [link](https://blog.csdn.net/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;
}

难点

  1. 其实广度遍历没什么,但是如何打印路径有点编程能力。
    答:这里采用二维矩阵记录父节点的方法。建立一个Point 类型的矩阵,每个值表示其父节点(当然可能有多个,但这里只考虑了一个父节点,不影响的)。
  2. 如何自定义一个自设计类型的矩阵。
    答:重指针+组长数组指针+类型指针

解答
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行,然后遍历他,给每个单个指针进行赋值。
到此,就可以用双下标的方法访问了!
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值