标签:attr 隔离 引用类型 概念 针对 转换 简单实现 内存 -name
    function foo(){
        ...foo(...)...
    }1. 假设递归函数已经写好
2. 寻找递推关系
3. 将递推关系的结构转换为递归体
4. 将临界条件加入到递归体中分析:
寻找递推关系: 就是 n 与 n-1 ,或 n-2 之间的关系
sum(n) == sum(n-1) + n
var res = sum(100);
var res = sum(99) + 100;将递归结构转换成递归体
function sum(n){
    return sum(n-1) + n;
}递归函数
function sum(n){
    if(n==1) return 1;
    return sum(n-1) + n;
}递归体
function foo(n){
return foo(n) = sum(n-1)+2;
}递归函数
function foo(n){
    if(n == 0) return 1;
    return foo(n-1) + 2;
}递归体
function sum(n){
return foo(n) + sum(n-1);
}递归函数
```
function foo(n){
if(n == 0) return 1;
return foo(n-1) + 2;
}
function sum(n){
if(n == 0) return 1;
return foo(n) + sum(n-1);
}
```
    function fn(n){
        return fn(n) = (n-1) + 2
    }
    function sum(n){
        return sum(n) = fn(n) + sum(n-1);
    }
## 数列 1,1,2,4,7,11,16...求第 n 项,求前n项和
* 分析
    1. 假设已知函数 foo(n) 为第n项
    2. 递归关系
        **从第 0 项开始计算**
        * 第 0 项, 1 => foo(0) + 0 = foo(1)
        * 第 1 项, 2 => foo(1) + 1 = foo(2)
        * 第 2 项, 3 => foo(2) + 2 = foo(3)
        * ...
        * 第 n-1 项, n => foo(n-1) + n-1 = foo(n)
        * foo(n) = foo(n-1) + n-1;
        **从第 1 项开始计算**
        * 第 1 项, 2  =>  fn( 1 ) + 0 = fn( 2 )
        * 第 2 项, 3  =>  fn( 2 ) + 1 = fn( 3 )
        * 第 3 项, 4  =>  fn( 3 ) + 2 = fn( 4 )
        * ...
        * foo(n) = fn(n-1) + n - 2
        * 如果从 0 开始
0  1  2  3  4  5   6
1, 1, 2, 4, 7, 11, 16,
    * 如果从 1 开始1  2  3  4  5  6   7
1, 1, 2, 4, 7, 11, 16    3. 递归体
function foo(n){
    return foo(n-1)+n-1;
}    4. 临界条件
        * foo(0) == 1;
        * foo(1) == 1;
    5. 递归函数
function foo(n){
    if(n == 0) return 1;
    return foo(n-1) + n -1;
}    * 分析
        1. 假设已知函数 sum(n)为前n项和
        2. 递归关系
            * sum(n) = foo(n) + sum(n-1);
        3. 递归体function sum(n){
    return foo(n) + sum(n-1);
}        4. 临界条件
            * sum(0) = 1;
        5. 递归函数
function sum(n){
    if(n == 0) return 1;
    return foo(n) + sum(n-1);
}
## Fibonacci数列(斐波那契数列)
    1,1,2,3,5,8,13,21,34,55,89...求第 n 项
* 分析
1. 假设已知 fib(n) 为第 n 项
2. 递归关系
    * fib(n) = fib(n-1) + fib(n-2)
 3. 递归体function fib(n){
    return fib(n-1)+fib(n-2);
}4. 临界条件
   * fib(0) == 1
   * fib(1) == 1
        5. 递归函数function fib(n){
    if(n == 0 || n ==1) return 1;
    return fib(n-1) + fib(n-2);
}
# 高级递归练习
## 阶乘
 概念:
    * 阶乘是一个运算, 一个数字的阶乘表示的是从 1 开始 累乘到这个数字.
    * 例如 3! 表示 `1 * 2 * 3`. 5! 就是  `1 * 2 * 3 * 4 * 5`. 规定 0 没有阶乘,
    * 阶乘 从 1 开始.
    * 分析:
1. 假设已知 foo(n) 为 1-n 的积
2. 递归关系
        * foo(n) = foo(n-1) * n
3. 递归体function foo(n){
    return foo(n-1) * n
}4. 临界条件
        * foo(1) == 1
5. 递归函数function foo(n){
    if( n == 1) return 1;
    return foo(n - 1) * n;
}
## 求幂
* 概念:
    求幂就是求 某一个数 几次方
    2*2 2 的 平方, 2 的 2 次方
    求 n 的 m 次方
    最终要得到一个函数 power( n, m )
    n 的 m 次方就是 m 个 n 相乘 即 n 乘以 (m-1) 个 n 相乘
* 分析
1. 假设已知函数 power(n,m) 为 n 的 m 次幂
2. 递归关系
* power(n,m-1) * n
3. 递归体function power(n,m){
    return power(n,m-1) * n;
}4. 临界条件
    * m == 1 ,return n
    * m == 0 ,reutnr 1
5. 递归函数function power(n,m){
    if(m == 1) return n;
    return power(n,m-1) * n;
}
# 深拷贝,使用递归方式
概念:
1. 如果拷贝的时候, 将数据的所有引用结构都拷贝一份, 那么数据在内存中独立就是深拷贝(内存隔离,完全独立)
2. 如果拷贝的时候, 只针对当前对象的属性进行拷贝, 而属性是引用类型这个不考虑, 那么就是浅拷贝
3. 拷贝: 复制一份. 指将对象数据复制.
4. 在讨论深拷与浅拷的时候一定要保证对象的属性也是引用类型.
实现方法:
5. 如果要实现深拷贝那么就需要考虑将对象的属性, 与属性的属性,都拷贝过来
6. 分析(2个参数,简单实现)
    1. 假设已经实现 clone ( o1, o2),将对象 o2 的成员拷贝一份交给 o1
    2. 递推关系
        * 混合方法,将 o2 的成员拷贝到 o1 中
    ```
        function clone( o1, o2){
            for(var key in o2){
                o1[key] = o2[key];
            }
        }
    ```
        * 假设方法已经实现,如果 o2[key] 是对象
        * 继续使用这个方法
        * 需要考虑 o2[key] 是引用类型,再一次使用clone函数
        * 如果 o2[key] 不是引用类型,那么直接赋值
    3. 临界条件
        * 因为是 for in 循环,没有成员遍历时,自动结束
    4. 递归函数function clone(o1,o2){
    for(var key in o2){
        if(typeof o2[key] == ‘object‘){
            o1[key] = {};
            clone(o1[key],o2[key])
        }else{
            o1[key] = o2[key];
        }
    }
}复杂实现(一个参数)
    原理: clone(o) = new Object; 返回一个对象
    递归函数function clone(o){
    var temp = {};
    for(var key in o){
        if(typeof o[key] == ‘object‘){
            temp[key] = clone(o[key]);
        }else{
            temp[key] = o[key];
        }
    }
    return temp;
}
# 使用递归实现 getElementsByClassName
    html结构:<div>
    <div>1
        <div class="c">2</div>
        <div>3</div>
    </div>
    <div class="c">4</div>
    <div>5
        <div>6</div>
        <div class="c">7</div>
    </div>
    <div>8</div>
</div>    分析
        1. 实现一个方法byClass()需要的参数是:
            node: 在某个节点上寻找元素
            className: 需要寻找的className
            arr: 找到的元素存储到这个数组中
        2. 遍历 node 的子节点,
        3. 查看这个子节点是否还有子节点,如果没有直接存储到数组中,如果有就继续递归
var arr = [];
function byClass(node, className, arr){
    //得到传入节点的所有子节点
    var lists = node.childNodes;
    for(var i = 0;i< lists.length;i++){
        //判断是否有相同className元素
        if(arr[i],className == className){
            arr.push(arr[i]);
        }
        //判断子节点是否还有子节点
        if(arr[i].childNodes.length > 0){
            byClass(arr[i],className,arr);
        }
    }
}标签:attr 隔离 引用类型 概念 针对 转换 简单实现 内存 -name
原文地址:https://www.cnblogs.com/xiewangfei123/p/12105397.html