var Stack = (function(){
var items = new WeakMap();
//先入后出,后入先出
class Stack{
constructor(){
items.set(this,[]);
}
push(ele){
//入栈
var ls = items.get(this);
var len = ls.length;
if(len > 0 && ls[len-1] <= ele){
throw new Error("汉罗塔错误")
return ;
}
ls.push(ele);
}
pop(){
//出栈
var ls = items.get(this);
return ls.pop();
}
size(){
//获取栈的长度
var ls = items.get(this);
return ls.length;
}
print(){
//打印栈
var ls = items.get(this);
return ls.toString();
}
}
return Stack;
})(); var stack1 = new Stack();
var stack2 =new Stack();
var stack3 = new Stack(); const num = 3; //汉诺塔的级数 for(var i = num; i >= 1; i-- ){
stack1.push(i);
}
var obj = {
"A":stack1,
"B":stack2,
"C":stack3
}
function hanoi(disc,a,b,c){
if(disc>0){
hanoi(disc-1,a,c,b);
console.log(' 移动 '+ disc + ' 号圆盘 ' + ' 从 ' + a + ' 移动到 ' + c);
obj[c].push(obj[a].pop()); //转移数组
hanoi(disc-1,b,a,c);
}
} //开始之前
console.log(stack1.print());
console.log(stack2.print());
console.log(stack3.print());
console.log("------------------------------"); hanoi(obj["A"].size(),"A","B","C"); //结果
console.log(stack1.print());
console.log(stack2.print());
console.log(stack3.print());

  

"汉诺塔"是印度的一个古老传说,也是程序设计中的经典的递归问题,是一个著名的益智游戏:

  题目如下:

    塔上有三根柱子和一套直径各不相同的空心圆盘,开始时源柱子上的所有圆盘都按从大到小的顺序排列。目标是通过每一次移动一个圆盘到另一根柱子上,最终把一堆圆盘移动到目标柱子上,过程中不允许把较大的圆盘放置在较小的圆盘上;

寻找规律(把所有的圆盘移动到C):

  1)n(圆盘个数) == 1

    第一次:1号盘  A -> C      sum(移动次数) = 1

  2)n == 2

    第一次:1号盘 A -> B

    第二次:2号盘 A -> C

    第三次:1号盘 B -> C  sum = 3

  3)n == 3

    第一次:1号盘 A -> C

    第二次:2号盘 A -> B

    第三次:1号盘 C -> B

    第四次:3号盘 A -> C

    第五次:1号盘 B -> A

    第六次:2号盘 B -> C

    第七次:1号盘 A -> C  sum = 7

  以此类推...

  故不难发现规律,移动次数为:sum = 2^n - 1 

算法分析(递归):

  把一堆圆盘从一个柱子移动另一根柱子,必要时使用辅助的柱子。可以把它分为三个子问题:

    首先,移动一对圆盘中较小的圆盘到辅助柱子上,从而露出下面较大的圆盘,

    其次,移动下面的圆盘到目标柱子上

    最后,将刚才较小的圆盘从辅助柱子上在移动到目标柱子上

   把三个步骤转化为简单数学问题:

    (1)     把 n-1个盘子由A 移到 B;

    (2)     把 第 n个盘子由 A移到 C;

    (3)     把n-1个盘子由B 移到 C;

 例如:有A上有4个盘子
    (1) 把 1-3由 A 移动到 B
    (2) 把 4 由 A 移动到 C
    (3) 把 1-3 由 B 移动到 C

 那么当A有100个盘子的时候

  函数 hanoi 会就相当于一个大哥(入口),在100的时候,他告诉后面的小弟(回调),你帮我解决上面的1-99搬运好位置,这个小弟(回调),又找自己下面的小弟(回调),处理一下 1-88...这样回调下去,最后就变成最简单的单个移动问题了

  我们创建一个JS函数,当它调用自身的时候,它去处理当前正在处理圆盘之上的圆盘。最后它回一个不存在圆盘去调用,在这种情况下,它不在执行任何操作。

js模拟栈---汉诺塔的更多相关文章

  1. [js - 算法可视化] 汉诺塔(Hanoi)演示程序

    前段时间偶然看到有个日本人很早之前写了js的多种排序程序,使用js+html实现的排序动画,效果非常好. 受此启发,我决定写几个js的算法动画,第一个就用汉诺塔. 演示地址:http://tut.ap ...

  2. js递归解决汉诺塔问题

    汉诺塔是一个印度的古老传说.有三个圆柱,其中一个圆柱上放着若干圆盘,这些圆盘从上到下,直径递增,利用一个辅助圆柱,将原来柱子上的圆盘放到另一个柱子上,依旧是从上到下直径递增. 汉诺塔是一个经典的递归案 ...

  3. 【C语言】汉诺塔问题

    之前遇见这个问题,非常费劲地理解了,并写出代码,然后过段时间,再遇见这个问题,又卡住了,如此反反复复两三次,才发现自己对递归的理解依然很肤浅.今天无聊,重温<算法:c语言实现>一书,又遇见 ...

  4. 【LintCode·容易】用栈模拟汉诺塔问题

    用栈模拟汉诺塔问题 描述 在经典的汉诺塔问题中,有 3 个塔和 N 个可用来堆砌成塔的不同大小的盘子.要求盘子必须按照从小到大的顺序从上往下堆 (如:任意一个盘子,其必须堆在比它大的盘子上面).同时, ...

  5. 数据结构--汉诺塔--借助栈实现非递归---Java

    /*汉诺塔非递归实现--利用栈 * 1.创建一个栈,栈中每个元素包含的信息:盘子编号,3个塔座的变量 * 2.先进栈,在利用循环判断是否栈空, * 3.非空情况下,出栈,检查是否只有一个盘子--直接移 ...

  6. 从"汉诺塔"经典递归到JS递归函数

    前言 参考<JavaScript语言精粹> 递归是一种强大的编程技术,他把一个问题分解为一组相似的子问题,每一问题都用一个寻常解去解决.递归函数就是会直接或者间接调用自身的一种函数,一般来 ...

  7. JS经典面试题汉诺塔

    我爱撸码,撸码使我感到快乐!大家好我是Counter.今天给大家分享的是利用JS将汉诺塔原理实现出来,其实主要是考察一个递归的思想,复杂的问题简单化,汉诺塔应该都知道吧,具体的游戏规则,可以百度查查, ...

  8. Python使用函数模拟“汉诺塔”过程

    运行效果: 源代码: 1 # -*- coding:utf-8 -*- 2 ##汉诺塔游戏开始 3 _times=0 #用于统计移动次数 4 def hannuota(nlist,mfrom,mpas ...

  9. [javascript]模拟汉诺塔

    看了博文自己动手写了代码. 这能值几个钱? 请写代码完成汉诺塔的算法:void Hanoi(int maxLevel); 比如2层汉诺塔,需要打印(Console.WriteLine)出如下文本: A ...

随机推荐

  1. MongoDB数据库连接失败

    win10下原来一直在用的MongoDB突然连接不上了,报错如下: 解决方法是:net start MongoDB重启服务

  2. ABP之事件总线(4)

    在上一篇的随笔中,我们已经初步完成了EventBus,但是EventBus中还有诸多的问题存在,那么到底有什么问题呢,接下来我们需要看一看ABP中的源码是如何定义EventBus的. 1.第一个点 在 ...

  3. Shell----简单整理

    ------------------------------------------------------------------Shell脚本--------------------------- ...

  4. IBatisNet不常用到的配置(Dao.config ConnectionTimeout),居然不起作用(前辈留给我们的坑)

    IBattis 默认超时时间好像是30s,可多于这个时间总就会报错:DaoProxy : unable to intercept method name 'ExcuteQuery', cause : ...

  5. kafka集群扩容后的topic分区迁移

    https://www.cnblogs.com/honeybee/p/5691921.html kafka集群扩容后,新的broker上面不会数据进入这些节点,也就是说,这些节点是空闲的:它只有在创建 ...

  6. arcengine新建要素类

    ArcGIS里面新建数据集,看起来简单,平时都是默认创建,实际上好多细节问题我们都没注意到 一.在数据集上新建要素类: How to create a feature class within a f ...

  7. [nginx] 从源码编译安装NGINX

    nginx通过rpm包进行的安装和配置: [web][nginx] 初识nginx -- 使用nginx搭建https DPI解码测试环境 现在,要通过源码进行安装. 参考:https://nginx ...

  8. EF-CodeFirst-基础

    什么是Code-First Code-First主要用于领域驱动设计.在Code-First方法中,专注于应用程序的域,先开始为域实体创建类,而不是先设计数据库,然后创建与数据库设计相匹配的类.下图说 ...

  9. 【Python全栈-HTML】HTML如何做出分割线效果

    参考: https://blog.csdn.net/weixin_39198406/article/details/78827671 一.普通效果 <hr> <hr align=ce ...

  10. 【pyqtgraph】pyqtgraph-鼠标互动

    pyqtgraph绘图库官方文档学习-鼠标互动(mouse interaction) 鼠标互动 大多数使用pyqtgraph数据可视化的应用程序都会生成可以使用鼠标进行交互式缩放,平移和配置的小部件. ...