JS汉罗塔递归算法

507 阅读2分钟

寻找规律(把所有的圆盘移动到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;

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

代码实现

var hanoi = function(disc,src,aux,dst){

if(disc>0){

    hanoi(disc-1,src,dst,aux);

    console.log(' 移动 '+ disc +  ' 号圆盘 ' + ' 从 ' + src +  ' 移动到 ' +  dst);

    hanoi(disc-1,aux,src,dst)

}

}

hanoi(3,'A','B','C')

JS递归函数遍历Dom

递归函数可以非常高效的操作树形结构,在JavaScript有一种"天然的树形结构"浏览器端的文档对象模型(Dom)。每次递归调用时处理指定树的一小段。

我们定义一个walk_the_DOM函数,

1) 它从某个指定的节点开始,按指定HTML源码的顺序,访问树的每个节点

2)它会调用一个函数,并依次传递每个节点给它,walk_the_DOM调用自身去处理每一个节点 */ var walk_the_DOM = function walk( node , func ) {

func(node);

node = node.firstChild;

while (node) {

    walk( node , func );

    node = node.nextSibling;

 }    

}

在定义一个getElementByAttribute函数

1) 它以一个属性名称字符串和一个可选的匹配值作为参数

2) 它调用walk_the_DOM,传递一个用来查找节点属性名的函数作为参数,匹配得节点都会累加到一个数组中 */

    var getElementsByAttribute=function(att,value){
            var results=[];

            walk_the_DOM(document.body,function(node){
                
                var actual=node.nodeType===1&&node.getAttribute(att);
                
                if(typeof actual==='string' &&( actual===value|| typeof value!=='string')){
                
                    results.push(node);
                
                }
            });
            return results;
        }