1

一、递归的概念

在程序中函数直接或者间接调用自身的一种方法,就叫做递归。它通常把一个大型复杂的问题转化为一个与原问题相似的规模较小的问题来求解,递归策略只需少量的程序就可描述出解题过程中所需要的多次重复计算,大大减少了程序的代码了。

二、项目中用到的几个经典的递归

1. 求1-100的和
分析:

  1. 假设递归函数已经写好为sum,即sum(100),就是求1-100的和。
  2. 寻找递归关系。sum(n)===sum(n-1)+n。
  3. 将临界条件加入到递归中。sum(1)=1。

递归函数实现

function sum(n){
    if(n===1){
      return 1;
    }
    return sum(n-1)+n;
  }
  console.log(sum(100));

2. 每天凌晨定时启动定时器执行代码
分析:

  1. 假设递归函数已经写好了timerDay。
  2. 寻找递归关系,延迟多少时间递归一次

递归函数实现

function timerDay(functionname){
    var date=new Date();//获取当前时刻
    var nowday=date.getDate();//获取当前日期
    var executionTime=new Date();//执行时间
    executionTime.setDate(nowday+1);//设置第二天凌晨0点20为执行时间
    executionTime.setHours(0);
    executionTime.setMinutes(0);
    executionTime.setSeconds(20);
    return setTimeout(function(){
      functionname();
      timerDay(functionname);
    },executionTime-date);
  }
  function fn(){//具体执行什么内容
    console.log("现在凌晨0点20秒");
  }
  var settimtout=timerDay(fn);

这个递归没有临界点,是一个无线循环执行的递归函数,如果我们想停止递归,我们可以清楚延时定时器。

clearTimeout(settimtout);

3. 将一个数组按照内容递归成树形数组
分析:

  1. 定义树形对象
  2. 得到根节点
  3. 得到子节点(得到子节点一级一级数据用到了递归)
var list = [{
    id: 1,
    name: "一级分类:1",
    pid: 0,
  },
  {
    id: 2,
    name: "二级分类:1",
    pid: 1,
  },
  {
    id: 3,
    name: "三级分类:1",
    pid: 2,
  },
  {
    id: 4,
    name: "一级分类:2",
    pid: 0,
  }];
function treeObj(originObj) { //定义树形对象
  var obj = {};
  obj.id = originObj.id;
  obj.name = originObj.name;
  obj.pid = originObj.pid;
  obj['children'] = [];
  return obj;
}

function isRootNode(pid, list) { //判断是否是根节点
  for (var i = 0; i < list.length; i++) {
    var item = list[i];
    if (item && item.id === pid) {
      return false
    }
  }
  return true;
}

function getRootNodes(list) { //得到根节点
  var rootNodes = [];
  for (var i = 0; i < list.length; i++) {
    var item = list[i];
    if (isRootNode(item.pid, list)) {
      rootNodes.push(treeObj(item));
    }
  }
  return rootNodes;
}

function getChildNodes(rootNodes, list) { //遍历获取子节点
  if (list.length !== 0) {
    for (var i = 0; i < rootNodes.length; i++) {
      for (var j = 0; j < list.length; j++) {
        if (rootNodes[i].id === list[j].pid) {
          rootNodes[i].children.push(treeObj(list[j]));
        }
      }
      getChildNodes(rootNodes[i].children, list); //递归遍历子节点
    }
  }
  return rootNodes;
}

var result = [];
if (list === undefined || list.length === 0) {
  result = [];
} else {
  var rootNodes = getRootNodes(list);
  result = getChildNodes(rootNodes, list);
  console.log(result);
}

666888
334 声望10 粉丝

知其然且知其所以然。