经典算法-----迷宫问题(栈的应用)

news2024/11/25 8:20:31

目录

前言

迷宫问题

算法思路

1.栈的使用方法 

​编辑2.方向的定义

代码实现

栈的cpp代码:

栈的头文件h代码:

走迷宫代码:


前言

        今天学习一种算法问题,也就是我们常见的迷宫问题,本期我们通过前面学习过的数据结构---栈来去完美的解决这个问题,下面看问题!

迷宫问题

        给定一个迷宫,指明起点和终点,找出从起点出发到终点的有效可行路径,就是迷宫问题(maze problem)。

迷宫可以以二维数组来存储表示。0表示通路,1表示障碍。注意这里规定移动可以从上、下、左、右四方方向移动

int maze[6][6] = {
		{1,1,1,1,1,1},
		{1,0,0,1,1,1},
		{1,0,0,0,0,0},
		{1,0,1,1,1,0},
		{1,0,0,0,0,1},
		{1,1,1,1,1,1}
	};

算法思路

1.栈的使用方法 

        迷宫问题,二维数组外围全是1的围墙,在里面规定一个起始地点和终点,这里我们要想找到起点到终点的路径,就需要一个数据结构去储存这个路径,这里可以用到栈的后进先出的特点,每次进入到一个可通过的点,就把这个点存入到栈当中,直到遇到了死胡同的时候,就回到上一个点,这时候就进行出栈的操作,然后走另外一条路,直到走到终点为止。

2.方向的定义

了解了栈的使用方法,那这里就要去定义移动的方向了,当走到某一个点的时候就要考虑优先往那边走,这时候可以根据迷宫的入口和出口大致方向去决定优先方向,这里的迷宫入口在出口的西北方向,那么优先的方向我依次为东、南、西、北,也就是说优先往东走,其次是南、西、北。方向的移动可以根据当前坐标进行上下左右的移动,只需要去定义一个方向数组,然后加上这个数组的方向即可。

 方向的储存结构:

//试探方向存储结构
typedef struct {
	int xx, yy;
}Direction;
//东南西北
Direction dire[4] = { {0,1},{1,0},{0,-1},{-1,0} };

代码实现

栈的cpp代码:

#include<stdio.h>
#include<stdlib.h>

//数据类型
typedef struct datatype {
	int x, y, di;
}ElemType;
//节点
typedef struct node {
	ElemType data;
	struct node* next;
}Node;
//栈顶指示
typedef struct stack {
	int count;	//计数
	Node* point;
}Stack;


//创建节点
Node* create_node(ElemType data) {
	Node* new_node = (Node*)malloc(sizeof(Node));
	if (new_node) {
		new_node->data = data;
		new_node->next = NULL;
		return new_node;
	}
	else
	{
		printf("ERROR\n");
	}
}

//初始化
void stack_init(Stack* top) {
	top->count = 0;
	top->point = NULL;
}

int isEmpty(Stack* top) {
	if (top->count == 0) {
		return 1;
	}
	return 0;
}


//入栈
void push(Stack* top, ElemType data) {
	Node* new_node = create_node(data);
	if (new_node) {
		top->count++;
		if (top->count == 1) {//如果入栈是第一个节点的话
			top->point = new_node;
		}
		else
		{
			new_node->next = top->point;
			top->point = new_node;
		}
	}
	else
		return;
}


//出栈
Node* pop(Stack* top) {
	Node* pop_node = NULL;
	if (!isEmpty(top)) {
		pop_node = top->point;
		top->point = pop_node->next;
		top->count--;
	}
	return pop_node;
}


//递归输出路径
void show_path(Node* node) {
	if (!node)
		return;
	show_path(node->next);
	printf("(%d,%d)\n", node->data.x, node->data.y);
}

栈的头文件h代码:

#pragma once
//链表栈
//数据类型
typedef struct datatype {
	int x, y, di;
}ElemType;
//节点
typedef struct node {
	ElemType data;
	struct node* next;
}Node;
//栈顶指示
typedef struct stack {
	int count;	//计数
	Node* point;
}Stack;


void stack_init(Stack* top);
int isEmpty(Stack* top);
void push(Stack* top, ElemType data);
Node* pop(Stack* top);
void show_path(Node* node);

走迷宫代码:

#include<stdio.h>
#include<assert.h>
#include"stack.h"

//试探方向存储结构
typedef struct {
	int xx, yy;
}Direction;
//东南西北
Direction dire[4] = { {0,1},{1,0},{0,-1},{-1,0} };

//判断能不能走出去,路径放入到了栈里面去
bool Findpath(int maze[][6],Stack* stack ,Direction dir[],int startx,int starty,int endx,int endy) {
	//startx,starty是起点的坐标;endx、endy是终点的坐标.
	assert(stack);
	int x, y, di;
	int line, col;
	//初始化
	maze[startx][starty] = -1;
	ElemType start = { startx,starty,-1 };
	push(stack, start);

	while (!isEmpty(stack)) {
		Node* po = pop(stack);
		ElemType temp = po->data;
		x = temp.x;
		y = temp.y;
		di = temp.di++;
		//使得栈储存了一条通路
		while (di < 4) {
			line = x + dire[di].xx;
			col = y + dire[di].yy;
			if (maze[line][col] == 0) {
				//储存上一个节点的位置,入栈
				temp = { x,y,di };
				push(stack, temp);
				x = line;
				y = col;
				maze[line][col] = -1;
				if (x == endx && y == endy) {
					//把终点的位置入栈
					temp = { x,y,-1 };
					push(stack, temp);
					return true;
				}
				else
					di = 0;
			}
			else
				di++;
		}
	}
	return false;
}



int main() {
	int maze[6][6] = {
		{1,1,1,1,1,1},
		{1,0,0,1,1,1},
		{1,0,0,0,0,0},
		{1,0,1,1,1,0},
		{1,0,0,0,0,1},
		{1,1,1,1,1,1}
	};
	Stack stack;
	stack_init(&stack);
	printf("能否出去:%d\n", Findpath(maze, &stack, dire, 1, 1, 4, 4));
	show_path(stack.point);//输出遍历的结果
}

输出结果:

好了,以上就是本期的全部内容了,我们下次见咯!

分享一张壁纸: 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1056780.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

一种基于体素的射线检测

效果 基于体素的射线检测 一个漏检的射线检测 从起点一直递增指定步长即可得到一个稀疏的检测 bool Raycast(Vector3 from, Vector3 forword, float maxDistance){int loop 6666;Vector3 pos from;Debug.DrawLine(from, from forword * maxDistance, Color.red);while (loo…

Vue3切换路由白屏刷新后才显示页面内容

问题所在&#xff1a; 1.首先检查页面路由以及页面路径配置是否配置错误。 2.如果页面刷新可以出来那证明不是配置的问题&#xff0c;其次检查是否在根组件标签最外层包含了个最大的div盒子包裹内容。&#xff08;一般vue3是可以不使用div盒子包裹的&#xff09; 3.最后如果…

快速开发微信小程序之一登录认证

一、背景 记得11、12年的时候大家一窝蜂的开始做客户端Android、IOS开发&#xff0c;我是14年才开始做Andoird开发&#xff0c;干了两年多&#xff0c;然后18年左右微信小程序火了&#xff0c;我也做了两个小程序&#xff0c;一个是将原有牛奶公众号的功能迁移到小程序&#x…

【iptables 实战】04 高级用法:iptables模块之state扩展

一、场景描述 假设我们内部的主机&#xff0c;想访问新闻网站&#xff0c;即访问其80端口。要想正确地获取到http报文内容。我们对这个网络报文应该这么设置 出去的报文&#xff0c;目标端口&#xff0c;80端口&#xff0c;放行进入的报文&#xff0c;源端口&#xff0c;80端…

vertx的学习总结2

一、什么是verticle verticle是vertx的基本单元&#xff0c;其作用就是封装用于处理事件的技术功能单元 &#xff08;如果不能理解&#xff0c;到后面的实战就可以理解了&#xff09; 二、写一个verticle 1. 引入依赖&#xff08;这里用的是gradle&#xff0c;不会吧&#…

几个推荐程序员养成的好习惯

本文框架 前言case1 不想当然case2 不为了解决问题而解决问题case3 不留问题死角case4 重视测试环节 前言 中秋国庆双节至&#xff0c;旅行or回乡探亲基本是大家的选择&#xff0c;看看风景或陪陪家人确实是个难得的机会。不过我的这次假期选择了闭关&#xff0c;不探亲&#…

手机号码(作为查询参数)格式校验:@PhoneQuery(自定义参数校验注解)

目标 自定义一个用于校验&#xff08;作为查询参数的&#xff09;手机号码格式的注解PhoneQuery&#xff0c;能够和现有的 Validation 兼容&#xff0c;使用方式和其他校验注解保持一致。 校验逻辑 可以为 null 或 空字符串&#xff1b;不能包含空格&#xff1b;必须为数字序…

开放式耳机哪个好、百元开放式耳机推荐品牌

开放式耳机以其独特的设计和出色的性能优势&#xff0c;成为许多音乐爱好者的首选。与传统的入耳式耳机相比&#xff0c;开放式耳机给用户带来更加舒适的佩戴体验。无需插入耳道&#xff0c;避免了长时间佩戴带来的不适感&#xff0c;让你可以尽情享受音乐而不受干扰。此外&…

Codeforces Round 901 (Div. 1) B. Jellyfish and Math(思维题/bfs)

题目 t(t<1e5)组样例&#xff0c;每次给出a,b,c,d,m(0<a,b,c,d,m<2的30次方) 初始时&#xff0c;(x,y)(a,b)&#xff0c;每次操作&#xff0c;你可以执行以下四种操作之一 ①xx&y&#xff0c;&为与 ②xx|y&#xff0c;|为或 ③yx^y&#xff0c;^为异或 …

心连心,同一个地方,同一个程序员

Hi,all, 现在开始所有一线城市和二线城市建立程序员交流群,为了防止病毒以及一些丧心病狂的广告人士,现在各大群以程序员为基础,入群者必须为程序员,严谨广告和僵尸人士入群,有想加群者加我微信,备注城市。比如想加入南京程序员交流群,备注南京,或者微信聊天窗口私聊…

基于 QT 实现一个 Ikun 专属桌面宠物

Step0、实现思路 想到的思路有两种&#xff1a; 1、使用 QT 的状态机模式&#xff0c;参考官网文档&#xff0c;这个模式的解耦最佳 2、使用原生 Wigets&#xff0c;将窗口设置为透明无框&#xff0c;循环播放桌面宠物的状态 本文采用第二种思路&#xff0c;实现一个极简版…

湖南特色农产品销售系统APP /基于android的农产品销售系统/基于android的购物系统

摘 要 随着信息技术和网络技术的飞速发展&#xff0c;人类已进入全新信息化时代&#xff0c;传统管理技术已无法高效&#xff0c;便捷地管理信息。为了迎合时代需求&#xff0c;优化管理效率&#xff0c;各种各样的APP应运而生&#xff0c;各行各业相继进入信息管理时代&#x…

ThreeJS - 封装一个GLB模型展示组件(TypeScript)

一、引言 最近基于Three.JS&#xff0c;使用class封装了一个GLB模型展示&#xff0c;支持TypeScript、支持不同框架使用&#xff0c;具有多种功能。 &#xff08;下图展示一些基础的功能&#xff0c;可以自行扩展&#xff0c;比如光源等&#xff09; 二、主要代码 本模块依赖…

毕业设计选题uniapp+springboot新闻资讯小程序源码 开题 lw 调试

&#x1f495;&#x1f495;作者&#xff1a;计算机源码社 &#x1f495;&#x1f495;个人简介&#xff1a;本人七年开发经验&#xff0c;擅长Java、Python、PHP、.NET、微信小程序、爬虫、大数据等&#xff0c;大家有这一块的问题可以一起交流&#xff01; &#x1f495;&…

【QT】自定义组件ui类添加到主ui界面方法

1.添加自定义组件到项目中 add new选择如下 写好类方法&#xff0c;确定即可 2.将新创建的ui类加入到主ui界面 选中新创建ui类的父类空块&#xff0c;右键选择提升为 选择并添加新创建的类

Tomcat Servlet

Tomcat & Servlet 一、What is “Tomcat”?二、 What is “Servlet”?1、HttpServlet2、HttpServletRequest3、HttpServletResponse 一、What is “Tomcat”? Tomcat 本质上是一个基于 TCP 协议的 HTTP 服务器。我们知道HTTP是一种应用层协议&#xff0c;是 HTTP 客户端…

PWN 基础篇 Write Up

PWN 05 解题过程 给了两个文件&#xff0c;一个是asm后缀&#xff0c;汇编代码文件&#xff0c;另外一个file看看&#xff0c;32位i静态编译可执行文件 分析一下汇编代码&#xff0c;里面包含有两个节&#xff0c;data节 该代码片段只展示了数据段的一部分&#xff0c;缺少了…

[VIM]VIM初步学习-3

3-1 编写 vim 配置&#xff0c;我的 vim 我做主_哔哩哔哩_bilibili

【GESP考级C++】1级样题 闰年统计

GSEP 1级样题 闰年统计 题目描述 小明刚刚学习了如何判断平年和闰年&#xff0c;他想知道两个年份之间&#xff08;包含起始年份和终止年份&#xff09;有几个闰年。你能帮帮他吗&#xff1f; 输入格式 输入一行&#xff0c;包含两个整数&#xff0c;分别表示起始年份和终止…

(四)动态阈值分割

文章目录 一、基本概念二、实例解析 一、基本概念 基于局部阈值分割的dyn_threshold()算子&#xff0c;适用于一些无法用单一灰度进行分割的情况&#xff0c;如背景比较复杂&#xff0c;有的部分比前景目标亮&#xff0c;或者有的部分比前景目标暗&#xff1b;又比如前景目标包…