PHP汉诺塔问题的递归算法实现和迭代算法实现

经典递归算法—汉诺塔问题(含代码示例) 相传在古印度圣庙中,有一种被称为汉诺塔(Hanoi)的游戏。该游戏是在一块铜板装置上,有三根杆(编号A、B、C),在A杆自下而上、由大到小按顺序放置64个金盘(如图1)。游戏的目标:把A杆上的金盘全部移到C杆上,并仍保持原有顺序叠好。操作规则:每次只能移动一个盘子,并且在移动过程中三根杆上都始终保持大盘在下,小盘在上,操作过程中盘子可以置于A、B、C任一杆上。 阅读详情

实现代码

程序代码地址:https://github.com/ParrySMS/Exp/tree/master/ProLang/hannota

递归法 hannoRec.php

<?php
/**
 * Created by PhpStorm.
 * User: L
 * Date: 2018-4-15
 * Time: 2:07
 */

/** 递归实现
 * @param $id //盘子编号
 * @param $first //起点柱子
 * @param $middle //中介柱子
 * @param $end //终点柱子
 */
function hanRec($id, $first, $middle, $end,$counter)
{
    if ($id == 1) {
        move(1,$first,$end,$counter);
    } else {
        hanRec($id-1,$first,$end,$middle,$counter);
        move($id,$first,$end,$counter);
        $counter++;
        hanRec($id-1,$middle,$first,$end,$counter);
    }
}

function move($id,$from,$to,$counter){
    global $counter;
    $counter++;
   // echo "step: $counter, level $id from $from move to $to, <br/>";
}

迭代法 hannoIter

<?php

/**
 * Created by PhpStorm.
 * User: L
 * Date: 2018-4-17
 * Time: 2:38
 */
class Params{ //定义一个对象来保存参数状态
    public $id;
    public $num;
    public $first;
    public $middle;
    public $end;
    public $counter;

    /**
     * Params constructor.
     * @param $num
     * @param $first
     * @param $middle
     * @param $end
     * @param $counter
     */
    public function __construct($id,$num, $first, $middle, $end, $counter)
    {
        $this->id = $id;
        $this->num = $num;
        $this->first = $first;
        $this->middle = $middle;
        $this->end = $end;
        $this->counter = $counter;
    }

}


function hanIter($id,$num, $first, $middle, $end, $counter)
{
    $stack =init($id,$num, $first, $middle, $end, $counter);
    while($stack){
        //出栈
        $action = array_pop($stack);
       // var_dump($action);
        if($action->num ==1){
            move($action->id,$action->first,$action->end,$action->counter);
        }else{
            //入栈
            $next_stack = init($action->id,$action->num,$action->first, $action->middle, $action->end, $action->counter);
            $stack=array_merge($stack,$next_stack);
        }
    }

}

/** 入栈操作
 * @param $id //需要移动的盘子
 * @param $num //移动该盘子需要挪动的总盘子数量
 * @param $first
 * @param $middle
 * @param $end
 * @param $counter
 * @return array
 */
function init($id,$num,$first, $middle, $end, $counter)
{
    unset($stack);
    //注意入站出站顺序
    $stack = array();
    //第一次回调
    $stack[] =new Params($id-1,$num-1,$middle,$first,$end,$counter);
    //第二次回调
    $stack[] =new Params($id,1,$first, $middle, $end, $counter);
    //第三次回调
    $stack[] =new Params($id-1,$num-1,$first,$end,$middle,$counter);
    return $stack;

}

/** 若在测试用例中,由于两个文件都有此 move函数,函数重名,注释掉其中一个即可 

function move($id,$from,$to,$counter){
    global $counter;
    $counter++;
   // echo "step: $counter, level $id from $from move to $to, <br/>";
}

**/


执行时间测试脚本 test.php

<?php
/**
 * Created by PhpStorm.
 * User: L
 * Date: 2018-4-17
 * Time: 2:18
 */

require "hannoRec.php";
require "hannoIter.php";



define('TIMES', 100);
define('NUM', 10);

function rowTable()
{
    unset($row);
    $row = array();

    for ($i = 0; $i < TIMES; $i++) {
    $row = getSortRow($row);
    }

    foreach ($row as $r) {
        print <<< TR
 <tr>
       <td>$r->iter</td>
       <td>$r->rec</td>
    </tr>
TR;
    }
}

function getSortRow(array $row)
{
    $num = NUM;
    $counter= 0;
    $stime = microtime(true);
    hanIter($num, $num, 'A', 'B', 'C', $counter);
    $etime = microtime(true);
    $iterTime = 1000 * ($etime - $stime);

//    echo "<br/>";
    $counter = 0;
    $num = NUM;
    $stime = microtime(true);
    hanRec($num, 'A', 'B', 'C', $counter);
    $etime = microtime(true);
    $recTime = 1000 * ($etime - $stime);

    $row[] = (object)["iter" => $iterTime, "rec" => $recTime];
    return $row;
}


?>

<table border="1">
    <tr>
        <th>迭代 Iter/ms</th>
        <th>递归 Rec/ms</th>
    </tr>
    <?php rowTable(); ?>
</table>

参考

迭代法思路:https://wenku.baidu.com/view/dce79165b0717fd5360cdcdb.html

递归经典例题 --- 汉诺塔(图文详解) 保姆级带你了解汉诺塔 阅读详情

相关推荐

PHP迭代与递归实现无限级分类

主要为大家详细介绍了PHP迭代与递归实现无限级分类,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

php实现汉诺塔问题(递归)

简单的用php实现了汉诺塔问题的求解,使用递归调用,但是用php实现要是盘子的个数很多的话,运行起来会很慢的...汉诺塔主要是有三个塔座X,Y,Z,要求将三个大小不同,依小到大编号为1,2.....n的圆盘从A移动到塔座Z上,要求(1):每次只能移动一个圆盘(2):圆盘可以插到X,Y,Z中任一塔座上(3):任何时候不能将一个较大的圆盘压在较小的圆盘之上主要是运用了递归的思想,这里使用ph...

ako262246的博客 364

实证研究之|stata清洗charls数据

stata

qq_45313933的博客 6761

递归算法之汉诺塔问题(Tower of Hanoi)详细解读

汉诺塔问题(Tower of Hanoi)是一个经典的递归问题,由法国数学家 Édouard Lucas 于1883年提出。问题描述了如何将不同大小的圆盘从一个柱子移到另一个柱子,同时遵循特定规则。它是计算机科学中用来展示递归思想和算法设计的经典案例。

欢迎来到我的博客!这里是一个专注于计算机技术的分享平台,涵盖编程开发、算法研究、系统架构、软件工程等多个领域。无论你是初学者还是资深开发者,都能在这里找到有价值的内容。 6194

华为昇腾 Atlas 200I DK A2 开发板编程接口学习入门:系统安装和开发步骤、注意事项与典型案例实战

华为昇腾开发板编程接口指南:从入门到进阶 本文系统介绍了华为昇腾开发板的编程接口体系,涵盖MindXSDK和AscendCL两大核心框架。MindXSDK提供高层封装接口,适合快速搭建视觉应用;AscendCL则是底层接口,需手动管理设备内存。文章详细讲解了: 开发环境搭建步骤,包括系统配置、依赖安装 MindXSDK组件化编程流程(图像分类实例) AscendCL底层开发方法(内存管理、模型推理) 常见问题解决方案和调试技巧 两个典型应用实例(摄像头目标检测和图像分类) 针对小白开发者,推荐从MindXS

bother3000的博客 2426

基于STM32的智能垃圾分类机器人

垃圾分类是城市管理的重要环节,传统人工分拣效率低、成本高。本文设计了一款基于STM32的智能垃圾分类机器人,通过视觉识别与机械臂协同作业,实现垃圾自动分类与投放,适用于社区、公共场所等场景,可显著提升垃圾分类效率。:STM32H743(480MHz Cortex-M7,支持AI加速)本系统实现了垃圾分拣的自动化,显著提升了分类效率。OV5640摄像头(500万像素,支持JPEG输出)支持4类垃圾识别(可回收/厨余/有害/其他)问题讨论,stm32的资料领取可以私信!超声波避障(探测距离0.1-4m)

stm32d1219的博客 1820

利用PHP递归算法实现汉诺塔

利用PHP实现 汉诺塔 汉诺塔(又称河内塔)问题是源于印度一个古老传说的益智玩具。大梵天创造世界的时候做了三根金刚石柱子,在一根柱子上从下往上按照大小顺序摞着64片黄金圆盘。大梵天命令婆罗门把圆盘从下面开始按大小顺序重新摆放在另一根柱子上。并且规定,在小圆盘上不能放大圆盘,在三根柱子之间一次只能移动一个圆盘。简而言之,有三根相邻的柱子,标号为A,B,C,A柱子上从下到上按金字塔状叠放着n个不同大...

homelam的博客 1115

短视频mssdk中get_token协议逆向与加密流程深度解析

本文深度解析了短视频mssdk中get_token协议的逆向分析与加密流程。通过抓包、Frida Hook、静态分析等手段,详细拆解了协议数据的Protobuf结构、设备信息采集来源,并重点剖析了其核心加密链路:zlib压缩、自定义TEA算法与AES-CBC加密,最终实现完整的协议模拟。

flower的专栏 557

汉诺塔的图解递归算法

汉诺塔(又称河内塔)问题是源于印度一个古老传说的益智玩具。大梵天创造世界的时候做了三根金刚石柱子,在一根...

Rnan_prince的博客 10万+

【gcc】跨版本兼容实战:高版本编译程序在低版本glibc环境下的部署方案

本文针对高版本gcc编译的程序在低版本glibc环境下部署的兼容性问题,提供了四种实战解决方案:静态编译的局限性、容器化部署的优雅方案、使用Devtoolset工具链的官方支持,以及最通用灵活的打包依赖SO发布方案。重点剖析了通过设置RPATH和Interpreter或使用patchelf工具,实现程序与自带库的独立部署,有效解决glibc版本鸿沟。

weixin_29237635的博客 362

【数据分析】R语言分段结构方程模型手把手教程(Piecewise Structural Equation Model)

分段结构方程模型(Piecewise Structural Equation Model, SEM)是一种用于分析变量之间因果关系的统计方法。它通过将复杂的因果关系分解为多个简单的线性模型来评估变量之间的直接和间接效应。与传统的结构方程模型(SEM)不同,分段结构方程模型不需要假设数据的多变量正态分布,因此在处理非正态数据时更为灵活。

专注生信领域 2650

php 实现汉诺塔

<?php /** * 递归法解汉诺塔问题 **/ function getStep($n, $a, $b, $c) { global $step; if ($n == 1) { $step++; echo "将圆盘 $n 从 $a 柱子 到 $c 柱子 <br />"; } else { getStep($n - 1, $

vvvbird的专栏 561

ML307R OpenCPU TCP使用

实现现象 平台下发数据,板子在收到数据之后,马上再发送到平台,通过串口助手可以看到已经接收到数据。ML307R TCP 是使用LWIP的标准的socket通信,具体TCP流程可以自行百度。实验目的:实现把接收的数据再发送到服务端。因为是4G,所以必须用外网的。

面朝大海春暖花开 2232

php有递归算法,PHP递归算法详解

本篇文章主要介绍PHP递归算法详解,感兴趣的朋友参考下,希望对大家有所帮助。遇到需要设计树节点的数据库结构,以及需要读出来的树节点数据结构!大家是否会选择用数据库的查询方式来获取树结构呢?//曾经的数据库查询获取方式$res = $this->db->query("select * from menu where pid = 0");foreach($res as $k=>$v)...

weixin_29126497的博客 292

C#上位机国产化适配全方案:兼容统信UOS+鲲鹏/昇腾+国产PLC,可直接交付国企项目

去年下半年,我帮天津滨海新区一家给一汽丰田做配套的汽车零部件国企,完成了3条产线、12套C#上位机的全栈国产化适配。这个项目的背景很典型,也很戳中国企客户的命门:一开始客户找了两家本地的集成商,都没搞定:第一家只会用.NET Framework,根本不知道怎么在统信UOS上跑C#;第二家勉强用.NET Core 3.1跑起来了,但和汇川国产PLC的通信丢包率高达1.2%,产线根本不敢用。我们接手后,用了2个月完成全栈适配:从Windows Server 2019迁移到统信UOS 1070d服务器版,从.NE

这里只有干货:从 Modbus 通信到 MES 对接,从 YOLO 训练到工控机部署,带你搞定工业软件开发全流程。 498

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

递归思想和实例

先给一个简单的阶乘例子: public static int getDg(int x){ System.out.println(x); if (x==1) { return 1; } if (x<4) { return x * getDg(x-1); } else { return x * getDg(x-1); } } 很多人对递归的理

cxj5221的博客 348

lwip-2.0.3

lwip是瑞典计算机科学院(SICS)的Adam Dunkels 开发的一个小型开源的TCP/IP协议栈。实现的重点是在保持TCP协议主要功能的基础上减少对RAM 的占用。

【轻松掌握数据结构与算法】算法设计技巧

在前面的章节中,我们已经看到了许多用于解决不同类型问题的算法。在解决新问题之前,通常的做法是寻找当前问题与其他已解决问题之间的相似性。这有助于我们更容易地找到解决方案。在本章中,我们将探讨算法的不同分类方法,并在后续章节中重点介绍其中的几种(贪心算法、分治算法、动态规划)。

Whoisbug的博客 1092

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

数字图像处理技术详解程序_程序员:Java数据结构与算法——第十六章·算法设计技术详解...

16.1引言 在求解一个新问题时,通常的思路是寻找当前问题与已解决问题之间的相似之处,从而轻松找到新问题的求解方法。 本章将对各种算法按照不同的方法进行分类,然后在随后的3章中分别介绍3个算法设计思想(即贪婪、分治和动态规划)。16.2分类关于算法的分类有很多种方法,下面列出了其中的一些分类方法:●实现方法●设计方法●其他分类方法16.3 按实现方法分类1.递归或迭代 ...

weixin_40001372的博客 139

java设计一个o n 2 的算法_程序员:Java数据结构与算法——第十六章·算法设计技术详解...

16.1引言在求解一个新问题时,通常的思路是寻找当前问题与已解决问题之间的相似之处,从而轻松找到新问题的求解方法。本章将对各种算法按照不同的方法进行分类,然后在随后的3章中分别介绍3个算法设计思想(即贪婪、分治和动态规划)。16.2分类关于算法的分类有很多种方法,下面列出了其中的一些分类方法:●实现方法●设计方法●其他分类方法16.3 按实现方法分类1.递归或迭代递归算法指算法反复地调用自身,直到...

weixin_34438187的博客 175

程序员:Java数据结构与算法——第十六章·算法设计技术详解

Java数据结构与算法-第十六章·算法设计 16.1引言 在求解一个新问题时,通常的思路是寻找当前问题与已解决问题之间的相似之处,从而轻松找到新问题的求解方法。 本章将对各种算法按照不同的方法进行分类,然后在随后的3章中分别介绍3个算法设计思想(即贪婪、分治和动态规划)。 16.2分类 关于算法的分类有很多种方法,下面列出了其中的一些分类方法: ●实现方法 ●设计方法...

程序员界 610

递归解决汉诺塔问题(原理图解+代码实现+递归讲解)

那有n个时我们仍当作两个处理。 1.把上面n-1个当作一个整体,放在mid柱子, 2.a柱一个圆盘放到c柱, 3.b柱n-1个圆盘(此时当作整体)放到c柱。

m0_74110717的博客 1165

递归和迭代_用 递归 与 迭代 实现汉诺塔问题(PHP实现)

汉诺塔问题汉诺塔(Hanoi)的游戏。该游戏是在一块铜板装置上,有三根杆(编号A、B、C),在A杆自下而上、由大到小按顺序放置N个金盘(如下图)。游戏的目标:把A杆上的金盘全部移到C杆上,并仍保持原有顺序叠好。操作规则:每次只能移动一个盘子,并且在移动过程中三根杆上都始终保持大盘在下,小盘在上,操作过程中盘子可以置于A、B、C任一杆上。实现代码点击即可即可跳转到Github程序代码递归法 hann...

weixin_29384861的博客 212

详解汉诺塔:递归树与纯函数编程

第一种递归写法中,过程信息全部丢失,只有n==1的cout,相当于只有一个活跃的State& s,每次传递都对其进行修改,因此涉及到调用深度问题无法读取;而在纯函数写法中,生成的是State s临时变量,相当于有多个短暂的副本,每次函数的运行状态都得到了读取和拼接。汉诺塔问题只有三次调用自身,如果遇到更复杂的问题,恐怕是很难按照逻辑顺序写出非纯函数的。

2301_76616273的博客 1480

(转)汉诺塔的图解递归算法

【转载原因:汉诺塔递归非常清晰】 【转载原文:https://dmego.me/2016/10/16/hanoi】 起源 汉诺塔(又称河内塔)问题是源于印度一个古老传说的益智玩具。大梵天创造世界的时候做了三根金刚石柱子,在一根柱子上从下往上按照大小顺序摞着64片黄金圆盘。大梵天命令婆罗门把圆盘从下面开始按大小顺序重新摆放在另一根柱子上。并且规定,在小圆盘上不能放大圆盘,在三根柱子之...

小蚯蚓的博客 1011

汉诺塔的递归算法与解析

从左到右 A B C 柱 大盘子在下, 小盘子在上, 借助B柱将所有盘子从A柱移动到C柱, 期间只有一个原则: 大盘子只能在小盘子的下面. 如果有3个盘子, 大中小号, 越小的越在上面, 从上面给盘子按顺序编号 1(小),2(中),3(大), 后面的原理解析引用这里的编号. 小时候玩过这个游戏, 基本上玩到第7个,第8个就很没有耐心玩了,并且操作的动作都几乎相同觉得无聊. 后来学习编程, 认识到递归, 用递归解决汉诺塔的算法也是我除了简单的排序算法后学习到的第一种算法. 至于 递归,简单来说就是方法内

所有热爱的东西都要不余遗力 5789

汉诺塔递归算法精讲

本文从手动解决汉诺塔问题,逐步进行过程抽象,对递归算算法解决汉诺塔问题进行了详细的归纳和解释。

退休码农的自留地 5534
上一篇: PHP快速排序问题的递归算法实现和迭代算法实现
下一篇: web开发文章分享 -- 从摸门到入门
维生素P
博客等级 码龄9年 14粉丝 32原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值