递归总结应用

2021-03-17  本文已影响0人  幸宇

说到递归,一直以来在工作中的确是有用到过,但并没有进行总结和进一步的理解,看到前人做过很多的总结,这里也自己整理记录一下,方便日后翻阅;
1、什么是递归?
在js中,我们写页面,写函数,写方法的时候用到过,简单来说,递归就是在一个函数的方法里 调用 自己;

2、怎么去写递归?
首先设置终止条件,满足条件则返回;否则,重复调用自身;举个粒子:
a、实现 1234n的值?

var funVal=function(n){
//设置终止条件
if(n<=1) return 1;
//否则重复调用自身
return funVal(n-1) * n
}

b、求第n项的值,斐波那契数列:1,1,2,3,5,8,13...第n项值是多少?
很显然从第3项起是前面两项的数值的和,那么终止条件就有了,如果n==1 || n==2 返回 1;

var fibo = function(n){
// 如果是第一项或者第二项,则直接返回1
if(n==1||n==2) return 1;
//否则的话,返回前两项的和
return fibo(n-1)+fibo(n-2)
}
console.log(fibo(5))

3、工作中用到递归的时候
a、深拷贝取值

 当我们对象是json格式的对象时,没有特殊函数的时候,可以用到递归的思想来取到我们想要的数据:
**数据格式:**

copydata:[
        'abc',
        {
          name:zx,
          content:{
            c:2
          }
        },
        {
          arr:['3',4,'5']
        }
      ],

***方法:***

//判断是否是对象
    isObject(obj){
      var type = typeof obj;
      return type === 'function' || type === 'object' && !!obj;
    },

    //用递归的方式进行深拷贝
    deepClone(obj){
      if(!this.isObject(obj)) return obj;         //判断是否是对象或者是数组,如果不是则返回原始值

      var result = new obj.constructor();         //创建一个对象返回;巧妙避免对当前数据是数组还是对象的判断
      
      for(var i in obj){
        if(obj.hasOwnProperty(i)){
          result[i] = this.deepClone(obj[i]);
        }
      }
      return result;
    },

***调用:***
let obj = this.deepClone(this.copydata)
console.log("copyobj======",obj)

b、遍历元素所有子节点

dom 结构:


<template>
  <div class="hello" id="hello">
    <div>递归调用</div>
    <p>这是文字。。。。。</p>
  </div>
</template>

方法:

//递归遍历元素的所有子节点 给每个元素节点添加'data-index'属性
    /**
     * @param {节点或元素} root 要递归的节点或元素
     * @param {function} callback 每一次遍历的回调函数
     * 
     */
    getChildNodes(root,callback){
      // 判断是否存在子元素
      if(root && root.children && root.children.length){
        //将子元素转换成可遍历的数组
        Array.from(root.children).forEach(node=>{
          callback && typeof callback === 'function' && callback(node);
          //递归子元素,重复上面操作
          this.getChildNodes(node,callback)
        })
      }
    },

调用:
const root = document.getElementById('hello');
    this.getChildNodes(root,function(node){
      console.log(node,"node=====")
      node.setAttribute('data-index','123')
  })

image.png

c、遍历树形结构

数据:
tree:{
        name: '电脑',
        children: [
          {
            name: 'F盘',
            children: [
              {
                name: '照片',
                children: []
              },
              {
                name: '文件',
                children: [
                  {
                    name: '工作文件',
                    children: [
                      {
                        name: '报告',
                        children: []
                      }
                    ]
                  }
                ]
              }
            ]      
          },
          {
            name: 'E盘',
            children: [
              {
                name: '视频',
                children: [
                  {
                    name: 'js教程',
                    children: []
                  }
                ]
              }
            ]
          }
        ]

      }


方法:采用深度优先原则
// 树形结构递归  遍历树形结构深度优先原则:就是顺着一个节点延伸下去,先遍历它的第一个子节点,
    // 然后是第一个孙节点,然后重孙节点,直到没有子节点为止。即先纵深遍历完之后在遍历同级的其他节点。
    deepTraversal(root,cb){
      let that = this;
      if(!root) return;
      cb && typeof cb === 'function' && cb(root);
      if(root.children && root.children.length){
        var i = 0,node;
        for(;node=root.children[i++];){
          that.deepTraversal(node,cb);
        }
      }
    }

调用:
//遍历树形结构
    this.deepTraversal(this.tree,function(node){
      console.log("打印名字=====",node.name)
    })
image.png
上一篇 下一篇

猜你喜欢

热点阅读