[路飞]_递归&分治,学算法的科目一

425 阅读1分钟

递归

递归的本质就是循环,通过函数体来进行的循环,函数自己调自己。每个递归都要有一个终止条件,没有终止条件就是死循环。

  • 代码模板
function recursion(level, param1, param2, ...) {
  //递归终止条件
  if (level > MAX_LEVEL)
    return

  //数据处理
  processData(level, data)

  //调用自己,进入下一层
  recursion(level + 1, p1, ...)

  //如果需要,处理其它事情
  reverseState(level)
}
  • 递归例子

Fibonacci array: 1, 2, 3, 5, 8, 13, 21, 34, ...

function fib(n) {
  if (n === 0 || n === 1)
    return n

  return fib(n - 1) + fib(n - 2)
}

fib(6)执行过程

斐波那契数列执行过程.png

递归算法可能存在重复的子操作,可以用 Map 进行缓存。递归可用于一些高级算法,如分治。

分治 - Divde & Conquer

分治是把一个大问题分解为多个子问题,子问题一一解决,解决后归并子问题的结果,得到大问题的结果。它的好处是,可以进行并行计算,每个子问题互不相干,不需要等其它问题的处理结果,可以在多电脑上或多 CPU 上计算,所以速度更快。

分治与合并.png

  • 代码模板
function divide_conquer(problem, param1, param2, ...) {
  //分治退出条件
  if (!problem)
    return

  //准备数据,把大问题转换成小问题
  data = prepareData(problem)
  subproblems = splitProblem(problem, data)

  //对子问题进行分治
  subresult1 = divide_conquer(subproblems[0], p1, ...)
  subresult2 = divide_conquer(subproblems[1], p2, ...)
  subresult3 = divide_conquer(subproblems[2], p3, ...)

  //合并结果并返回
  result = processResult(subresult1, subresult2, subresult3, ...)
}