js模拟栈---汉诺塔
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模拟栈---汉诺塔的更多相关文章
- [js - 算法可视化] 汉诺塔(Hanoi)演示程序
前段时间偶然看到有个日本人很早之前写了js的多种排序程序,使用js+html实现的排序动画,效果非常好. 受此启发,我决定写几个js的算法动画,第一个就用汉诺塔. 演示地址:http://tut.ap ...
- js递归解决汉诺塔问题
汉诺塔是一个印度的古老传说.有三个圆柱,其中一个圆柱上放着若干圆盘,这些圆盘从上到下,直径递增,利用一个辅助圆柱,将原来柱子上的圆盘放到另一个柱子上,依旧是从上到下直径递增. 汉诺塔是一个经典的递归案 ...
- 【C语言】汉诺塔问题
之前遇见这个问题,非常费劲地理解了,并写出代码,然后过段时间,再遇见这个问题,又卡住了,如此反反复复两三次,才发现自己对递归的理解依然很肤浅.今天无聊,重温<算法:c语言实现>一书,又遇见 ...
- 【LintCode·容易】用栈模拟汉诺塔问题
用栈模拟汉诺塔问题 描述 在经典的汉诺塔问题中,有 3 个塔和 N 个可用来堆砌成塔的不同大小的盘子.要求盘子必须按照从小到大的顺序从上往下堆 (如:任意一个盘子,其必须堆在比它大的盘子上面).同时, ...
- 数据结构--汉诺塔--借助栈实现非递归---Java
/*汉诺塔非递归实现--利用栈 * 1.创建一个栈,栈中每个元素包含的信息:盘子编号,3个塔座的变量 * 2.先进栈,在利用循环判断是否栈空, * 3.非空情况下,出栈,检查是否只有一个盘子--直接移 ...
- 从"汉诺塔"经典递归到JS递归函数
前言 参考<JavaScript语言精粹> 递归是一种强大的编程技术,他把一个问题分解为一组相似的子问题,每一问题都用一个寻常解去解决.递归函数就是会直接或者间接调用自身的一种函数,一般来 ...
- JS经典面试题汉诺塔
我爱撸码,撸码使我感到快乐!大家好我是Counter.今天给大家分享的是利用JS将汉诺塔原理实现出来,其实主要是考察一个递归的思想,复杂的问题简单化,汉诺塔应该都知道吧,具体的游戏规则,可以百度查查, ...
- Python使用函数模拟“汉诺塔”过程
运行效果: 源代码: 1 # -*- coding:utf-8 -*- 2 ##汉诺塔游戏开始 3 _times=0 #用于统计移动次数 4 def hannuota(nlist,mfrom,mpas ...
- [javascript]模拟汉诺塔
看了博文自己动手写了代码. 这能值几个钱? 请写代码完成汉诺塔的算法:void Hanoi(int maxLevel); 比如2层汉诺塔,需要打印(Console.WriteLine)出如下文本: A ...
随机推荐
- [No0000138]软件开发基础知识
1. 本文目的 本文目的在于,介绍软件开发的各种基础知识 以实现,看了之后,对于软件开发的很多领域的基础知识有所了解 如此在进行后续的真正的软件开发时,遇到各种细节知识,才会明白由来和背景知识 第 1 ...
- Java NIO 与 IO之间的区别
概述 Java NIO提供了与标准IO不同的IO工作方式: Channels and Buffers(通道和缓冲区):标准的IO基于字节流和字符流进行操作的,而NIO是基于通道(Channel)和缓冲 ...
- Vue SSR 配合Java的Javascript引擎j2v8实现服务端渲染2创建Vue2+webpack4项目
前提 安装好nodejs并配置好环境变量,最好是 node10,https://nodejs.org/en/download/ 参考我之前的文章 debian安装nodejs Yarn &&a ...
- gfs故障恢复
GlusterFS更换故障Brick tanzhenchao关注0人评论3918人阅读2017-03-21 09:53:18 1 前言 笔者公司内有一套GlusterFS分布式存储,最近数据分区的 ...
- Isomorphism 同构
小结: 1.两个有限维度的向量空间,在同一数域下,是同构的 等价于 它们维数相等. Isomorphism 同构 0.1.8 Isomorphism. If U and V are vector sp ...
- Chap2:什么是shell[The Linux Command Line]
shell - a program that takes keyboard commands and passes them to the operating system to carry out ...
- [dpdk] SDK编译-简单扼要版
0. 前提: 环境是CentOS7,archlinux编译有问题,不知道却什么. 1. 解压: [root@dpdk dpdk]# tar Jxf dpdk-2.2.0.tar.xz 2. 设置环境变 ...
- 转:jdk动态代理实现
原文链接: jdk动态代理 注:文章中用常用的流程实现 动态代理,流程逻辑比较清晰.文章后面对 “为什么要使用接口” 原理分析还未细看. jdk的动态代理为什么用接口,内部是什么原理呢?看了几篇文章貌 ...
- 20165225《Java程序设计》第三周学习总结
20165225<Java程序设计>第三周学习总结 1.视频与课本中的学习: 遇到的问题: 问题如下,无法编译. 最后经同学点出要放在同一个打包的文件夹里,于是就运行成功了,下面是4_15 ...
- java 集合(一)ArrayList的继承树
这是ArrayList的继承树,它继承了AbstractCollection抽象类,AbstractCollection类实现了Collection接口,Collection接口继承Iterable接 ...