简单迷宫算法(递归与非递归C++实现)
假定迷宫如下:1代表墙,0代表道路,起点在(1,1),终点(11,9)(PS:下标从0开始计算)。
现在寻求一条路径能从起点到达终点(非最短)。
有两种解法:递归与非递归。
递归算法思路:
要用递归,就要寻找一个子问题,该子问题是递归的。很明显,这道题的子问题就是从8个方向(上下左右还有四个斜角)中寻找一个可行方向并向前走一步,该子问题(seekPath函数)的实现代码如下:
- struct offset{
- int x;
- int y;
- };
- offset move[]={{-,},{-,},{,},{,},{,},{,-},{,-},{-,-}};//8个不同行动方向下的x和y偏移量
- ][]={};//将数组所有节点访问位置0(未访问)
- ]={ ",
- ",
- ",
- ",
- ",
- ",
- ",
- ",
- ",
- ",
- ",
- "
- };//迷宫数组
- list<offset> s;//存放成功路径
- int seekPath(int x,int y){//行动一步
- int next_x,next_y;
- &&y==) ;//找到出口
- ;i<;i++){//朝8个方向试探下一步
- next_x=move[i].x+x;
- next_y=move[i].y+y;
- &&a[next_x][next_y]=='){//下一步未走过并且是道路
- mark[next_x][next_y]=;//标记该点已经走过
- if(seekPath(next_x,next_y)){
- offset a={next_x,next_y};
- s.push_front(a); //记录正确路径
- ;
- }
- }
- }
- &&y==){//死迷宫
- cout<<"failed"<<endl;
- }
- ;
- }
递归过程中,在每个点上有8个方向,在某个方向上若能满足“该方向点未走过并且是道路 ”的条件,即可执行下一步(下一步的方向从第一个方向重新开始计算),直到找到递归出口。递归出口自然是行走到终点的情况。
测试代码如下:
- int main(){//测试代码
- mark[][]=;
- ,))
- s.push_front(offset{,});
- list<offset>::iterator it=s.begin();
- while(it!=s.end()){
- cout<<"("<<it->x<<","<<it->y<<")";
- it++;
- }
- ;
- }
非递归算法思路:
我们首先需要一个辅助链表,链表的作用是为了记录正确路径。从起点开始,有8个方向,若能满足“该方向点未走过并且是道路 ”的条件,即可将该点放入表尾并执行下一步(下一步的方向从第一个方向重新开始计算),当8个方向都不能满足条件时,将该点从表尾删除并回退到上一个点。实现代码如下:
- #include <iostream>
- #include <list>
- using namespace std;
- struct offset{
- int x;
- int y;
- };
- struct point{
- int x;
- int y;
- };
- offset move[]={{-,},{-,},{,},{,},{,},{,-},{,-},{-,-}};//8个不同行动方向下的x和y偏移量
- ][]={};//将数组所有节点访问位置0(未访问)
- ]={ ",
- ",
- ",
- ",
- ",
- ",
- ",
- ",
- ",
- ",
- ",
- "
- };//迷宫数组
- int main(){//测试代码
- mark[][]=;
- list<point> lists;//存放路径
- point s={,};
- lists.push_back(s);
- while(!lists.empty()){
- s=lists.back();
- ;d<;d++){//朝8个方向试探下一步
- int x=s.x+move[d].x;
- int y=s.y+move[d].y;
- &&y==){//找到出口
- s.x=x;
- s.y=y;
- lists.push_back(s);
- goto end;
- }
- ){//下一步未走过并且是道路
- mark[x][y]=;
- point temp={x,y};
- lists.push_back(temp);
- s.x=x;
- s.y=y;
- d=;
- }
- }
- lists.pop_back();//删除不可达路径
- }
- cout<<"failed";
- end:list<point>::iterator it=lists.begin();
- while(it!=lists.end()){
- cout<<"("<<it->x<<","<<it->y<<")";
- it++;
- }
- ;
- }
简单迷宫算法(递归与非递归C++实现)的更多相关文章
- C#实现(递归和非递归)高速排序和简单排序等一系列排序算法
本人由于近期工作用到了一些排序算法.就把几个简单的排序算法.想冒泡排序,选择排序,插入排序.奇偶排序和高速排序等整理了出来,代码用C#代码实现,而且通过了測试.希望能给大家提供參考. ...
- 汉诺塔算法的递归与非递归的C以及C++源代码
汉诺塔(又称河内塔)问题其实是印度的一个古老的传说. 开天辟地的神勃拉玛(和中国的盘古差不多的神吧)在一个庙里留下了三根金刚石的棒,第一根上面套着64个圆的金片,最大的一个在底下,其余一个比一 个小, ...
- 汉诺塔算法c++源代码(递归与非递归)[转]
算法介绍: 其实算法非常简单,当盘子的个数为n时,移动的次数应等于2^n - 1(有兴趣的可以自己证明试试看).后来一位美国学者发现一种出人意料的简单方法,只要轮流进行两步操作就可以了.首先把三根柱 ...
- AJPFX:递归与非递归之间的转化
在常规表达式求值中: 输入为四则运算表达式,仅由数字.+.-.*./ .(.) 组成,没有空格,要求求其值. 我们知道有运算等级,从左至右,括号里面的先运算,其次是* ./,再是+.- : 这样我们就 ...
- 扩展欧几里德算法(递归及非递归实现c++版)
今天终于弄懂了扩展欧几里德算法,有了自己的理解,觉得很神奇,就想着写一篇博客. 在介绍扩展欧几里德算法之前,我们先来回顾一下欧几里德算法. 欧几里德算法(辗转相除法): 辗转相除法求最大公约数,高中就 ...
- 【Weiss】【第03章】练习3.11:比较单链表递归与非递归查找元素
[练习3.11] 编写查找一个单链表特定元素的程序.分别用递归和非递归实现,并比较它们的运行时间. 链表必须达到多大才能使得使用递归的程序崩溃? Answer: 实现都是比较容易的,但是实际上查找链表 ...
- 求字符串长度之递归与非递归的C语言实现
在上一篇中介绍了字符串拷贝的递归与非递归的实现,这里就不在赘述递归原理. 递归求字符串长度_strlen: 1 int _strlen(const char *src) 2 { 3 if( src = ...
- C语言实现 二分查找数组中的Key值(递归和非递归)
基本问题:使用二分查找的方式,对数组内的值进行匹配,如果成功,返回其下标,否则返回 -1.请使用递归和非递归两种方法说明. 非递归代码如下: #include <stdio.h> int ...
- 二叉树之AVL树的平衡实现(递归与非递归)
这篇文章用来复习AVL的平衡操作,分别会介绍其旋转操作的递归与非递归实现,但是最终带有插入示例的版本会以递归呈现. 下面这张图绘制了需要旋转操作的8种情况.(我要给做这张图的兄弟一个赞)后面会给出这八 ...
随机推荐
- scrapy formRequest 表单提交
scrapy.FormRequest 主要用于提交表单数据 先来看一下源码 参数: formdata (dict or iterable of tuples) – is a dictionary ( ...
- C# 中利用 CRC32 值判断文件是否重复
需要在 NuGet 中引用 Crc32.NET 包 直接贴代码了: using Force.Crc32; using System; using System.Collections.Generic; ...
- gdb cheat sheet
0x01 控制流 r run,运行程序. r < a.txt run,重定向输入 si step instruction 进入函数 ni next instruction 下一 ...
- Neutron:Firewall as a Service(FWaaS)
用户可以用它来创建和管理防火墙,在 subnet 的边界上对 layer 3 和 layer 4 的流量进行过滤. 传统网络中的防火墙一般放在网关上,用来控制子网之间的访问. FWaaS 的原理也 ...
- C++购书系统
C++购书系统——来自班里某位同学的小学期作业 这是一个购书系统,模拟网上购书的流程.用户可以在这个小程序里输入对应的数字进行浏览书籍信息,查看用户信息,查找书籍,购买书籍以及查询个人订单的操作. 以 ...
- java基础-02数据类型
基本类型 整数 byte byte 数据类型是8位.有符号的,以二进制补码表示的整数 最小值是 -128(-2^7) 最大值是 127(2^7-1) 默认值是 0 byte 类型用在大型数组中节约空间 ...
- think
https://github.com/crossoverJie/Java-Interview Java-Interview https://github.com/aalansehaiyang/tech ...
- select2 3.5.3 二级下拉及搜索
select2 [3.5.3]版本 select2 插件地址 http://select2.github.io/select2/ 支持搜索: JS代码,如果Group不需要勾选,goup不加id就可以 ...
- [算法]浅谈求n范围以内的质数(素数)
汗颜,数学符号表达今天才学会呀-_-# 下面是百度百科对质数的定义 质数(prime number)又称素数,有无限个. 质数定义为在大于1的自然数中,除了1和它本身以外不再有其他因数. 求质数的方法 ...
- PHP——??空合并运算符和?:三元运算符
前言 在上一篇随笔,用三元运算符简单写的一个东西,引发了对他的兴趣,所以打算研究下. PHP7的新特性: https://php.net/manual/zh/migration70.new-featu ...