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

标签: php
23人阅读 评论(0) 收藏 举报
分类:

实现代码

程序代码地址: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

查看评论

递归和迭代算法 [汉诺塔问题]

递归的基本概念:程序调用自身的编程技巧称为递归,是函数自己调用自己. 一个函数在其定义中直接或间接调用自身的一种方法,它通常把一个大型的复杂的问题转化为一个与原问题相似的规模较小的问题来解决,可以极大...
  • luobo140716
  • luobo140716
  • 2016-05-24 13:40:41
  • 3258

递归3: 汉诺塔的递归与迭代实现

递归实现与main(): /*------------------------------------------------------ 汉诺塔主要是有三个塔座X,Y,Z,要求将从小到大编号为 1...
  • yss28
  • yss28
  • 2013-10-18 11:23:38
  • 2347

DOS界面汉诺塔

  • 2012年07月08日 17:08
  • 328B
  • 下载

汉诺塔的递归算法 C++

  • 2013年10月18日 16:12
  • 933B
  • 下载

java中使用递归求解汉诺塔问题

最近帮朋友编写了一段代码,主要原理就是和解决汉诺塔问题类似,下面就开以此来讲解一下汉诺塔问题。 问题描述如下: 古代有一个梵塔,塔内有三个座A、B、C,A座上有64个盘子,盘子大小不等,大的在...
  • w_y_loong
  • w_y_loong
  • 2012-07-15 21:14:16
  • 6385

Java 递归实现汉诺塔问题

汉诺塔问题就是:有ABC三根柱子,A柱子上从上到下摞了很多体积依次递增的圆盘,如果将圆盘从A移动到C柱子,且依然保持从上到下依次递增。 class Hanio{ public void moveO...
  • lingzhm
  • lingzhm
  • 2015-04-10 21:47:42
  • 2500

汉诺塔_递归算法

  • 2013年06月27日 11:19
  • 723B
  • 下载

汉诺塔非递归算法分析与实现

汉诺塔的递归算法很容易理解,也非常容易实现。下面,本文讨论了汉诺塔问题的非递归算法,核心内容就是栈的使用技巧。 首先,对于每个柱子来说,就是一个栈,这个栈有个特点就是,大数放在下面,小数放在上面。在...
  • feihongchen
  • feihongchen
  • 2015-07-21 22:37:25
  • 6413

经典递归问题:汉诺塔(PHP实现)

寻常解汉诺塔是一个很经典的递归问题,汉诺塔的游戏规则描述是这样的 汉诺塔(又称河内塔)问题是源于印度一个古老传说的益智玩具。大梵天创造世界的时候做了三根金刚石柱子,在一根柱子上从下往上按照大小顺序...
  • falcom_fans
  • falcom_fans
  • 2017-08-02 19:12:03
  • 191

汉诺塔 经典递归算法 in python

#coding:utf-8#coding:utf-8 #汉诺塔问题 n = int(input("输入初始化时A塔上盘子的个数n:\n")) def move( n , A , B ,C ): if...
  • u014496330
  • u014496330
  • 2015-03-25 14:00:56
  • 3555
    个人资料
    持之以恒
    等级:
    访问量: 4009
    积分: 254
    排名: 30万+
    博客专栏