假定迷宫如下: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++实现)的更多相关文章

  1. C#实现(递归和非递归)高速排序和简单排序等一系列排序算法

        本人由于近期工作用到了一些排序算法.就把几个简单的排序算法.想冒泡排序,选择排序,插入排序.奇偶排序和高速排序等整理了出来,代码用C#代码实现,而且通过了測试.希望能给大家提供參考.     ...

  2. 汉诺塔算法的递归与非递归的C以及C++源代码

    汉诺塔(又称河内塔)问题其实是印度的一个古老的传说. 开天辟地的神勃拉玛(和中国的盘古差不多的神吧)在一个庙里留下了三根金刚石的棒,第一根上面套着64个圆的金片,最大的一个在底下,其余一个比一 个小, ...

  3. 汉诺塔算法c++源代码(递归与非递归)[转]

     算法介绍: 其实算法非常简单,当盘子的个数为n时,移动的次数应等于2^n - 1(有兴趣的可以自己证明试试看).后来一位美国学者发现一种出人意料的简单方法,只要轮流进行两步操作就可以了.首先把三根柱 ...

  4. AJPFX:递归与非递归之间的转化

    在常规表达式求值中: 输入为四则运算表达式,仅由数字.+.-.*./ .(.) 组成,没有空格,要求求其值. 我们知道有运算等级,从左至右,括号里面的先运算,其次是* ./,再是+.- : 这样我们就 ...

  5. 扩展欧几里德算法(递归及非递归实现c++版)

    今天终于弄懂了扩展欧几里德算法,有了自己的理解,觉得很神奇,就想着写一篇博客. 在介绍扩展欧几里德算法之前,我们先来回顾一下欧几里德算法. 欧几里德算法(辗转相除法): 辗转相除法求最大公约数,高中就 ...

  6. 【Weiss】【第03章】练习3.11:比较单链表递归与非递归查找元素

    [练习3.11] 编写查找一个单链表特定元素的程序.分别用递归和非递归实现,并比较它们的运行时间. 链表必须达到多大才能使得使用递归的程序崩溃? Answer: 实现都是比较容易的,但是实际上查找链表 ...

  7. 求字符串长度之递归与非递归的C语言实现

    在上一篇中介绍了字符串拷贝的递归与非递归的实现,这里就不在赘述递归原理. 递归求字符串长度_strlen: 1 int _strlen(const char *src) 2 { 3 if( src = ...

  8. C语言实现 二分查找数组中的Key值(递归和非递归)

    基本问题:使用二分查找的方式,对数组内的值进行匹配,如果成功,返回其下标,否则返回 -1.请使用递归和非递归两种方法说明. 非递归代码如下: #include <stdio.h> int ...

  9. 二叉树之AVL树的平衡实现(递归与非递归)

    这篇文章用来复习AVL的平衡操作,分别会介绍其旋转操作的递归与非递归实现,但是最终带有插入示例的版本会以递归呈现. 下面这张图绘制了需要旋转操作的8种情况.(我要给做这张图的兄弟一个赞)后面会给出这八 ...

随机推荐

  1. win10怎么进入和退出安全模式?

    在Win10系统里同时按下”Win+R“组合按键,在打开的运行对话框里输入命令:msconfig,然后点击确定,如下图所示. 点击打开系统配置窗口,选择引导选项卡,如下图所示. 在引导选项卡窗口下,将 ...

  2. LeetCode算法题-Reach a Number(Java实现)

    这是悦乐书的第310次更新,第331篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第179题(顺位题号是754).你站在无限数字线的0号位置.在目的地有个target.在 ...

  3. docker 发布方式尝试

    docker 发布方式尝试 目前有个小项目, 尝试用docker的方式来发布, 项目只有一个节点, 使用 kubenate 有点小题大做, 所以采用docker-compose来发布. 发布过程 GI ...

  4. vue源码分析—认识 Flow

    认识 Flow Flow 是 facebook 出品的 JavaScript 静态类型检查⼯具.Vue.js 的源码利⽤了 Flow 做了静态类型检查, 所以了解 Flow 有助于我们阅读源码 Flo ...

  5. java学习札记

    java学习札记 0x0 学习原因  本来打算大三再去跟着课程去学习java的,但是现在题目越来越偏向java,所以迫于无奈开启了java的学习篇章,同时也正好写个笔记总结下自己学习一门语言的流程. ...

  6. 通过 docker 搭建自用的 gitlab 服务

    前言 git 是当下如日中天的版本管理系统.现在如果不是工作在 git 版本管理系统之下,几乎都不好意思和人打招呼了.有很多现成的互联网的 git 服务提供给大家使用,例如号称程序员社交网络的 Git ...

  7. Counting Sort(Java)

    public static void countingsort(int[] a, int n) //n = a.length { int max = a[0], min = a[0]; for(int ...

  8. Python之路【第十七篇】:Django【进阶篇 】(转自银角大王博客)

    Model 到目前为止,当我们的程序涉及到数据库相关操作时,我们一般都会这么搞: 创建数据库,设计表结构和字段 使用 MySQLdb 来连接数据库,并编写数据访问层代码 业务逻辑层去调用数据访问层执行 ...

  9. Mysql中的explain和desc

    查询分析器 desc 和 explain 作用基本一样,explain速度快一点 explain 一条SQL语句出出现以下参数, 其中id,select_type,table 用于定位查询,表示本行参 ...

  10. CSS中字距,词距,首行缩进,字体大小,排版相关问题的探讨

    先说明下,这是在谷歌浏览器下字体显示等问题做个研究,火狐下有点差异,不过火狐占有率低,而且显示的没有谷歌那么合理,不管它先.IE卡的要死,半死不活,也懒得深入研究这些细节,字体排版上不是强迫症,差别也 ...