• [知识点] 2.2 递归与分治


    总目录 > 2 算法基础 > 2.2 递归与分治

    前言

    递归是一种非常常用的算法思想,太多太多地方使用了。

    (总目录:https://www.cnblogs.com/jinkun113/p/12528423.html

    子目录列表

    1、递归

    2、分治

    2.2 递归与分治

    1、递归

    递归的基本思想是函数直接或间接地调用自身,用两张图来分辨递归与枚举的区别:

    枚举是按部就班从起点到终点逐一处理或累加;递归时的求解过程就像剥洋葱皮一样一层层地深入,直到得到最终结果。所以,递归的代码往往为如下结构:

    int func(当前状态) {
        if (终止条件) return 最终结果;
        return func(下一状态);
    }

    也就是说,打一开始,我们就要知道我们求解的目的是什么,终点在何方。相比枚举,递归其实是一种逆向思维,因为它的主要步骤是从最外层先找到最里层,然后再从最里层开始处理问题。

    从结构上来看,递归的三大核心:

    ① 当前状态

    ② 终止条件

    ③ 下一状态

    明确了这三点,递归基本就成型了。

    在不建立在某种算法或者某种结构的前提下,其实单说递归是空洞的,它是作为各种算法的底层思想,所以如果要去理解它,去了解用到递归的算法要比了解递归的本质要来的轻松。所以,这里只给出几个密切相关的链接和一些代码,暂且不提算法本身的作用,只是用以体现递归的常用形式。

    ① 深度优先搜索 DFS(请参见:3.1 DFS / BFS

     1 void DFS(int x, int y, int p) {
     2     if (a[x][y] == 1) return;
     3     a[x][y] = 1;
     4     if (x == tx && y == ty) ans = min(p, ans);
     5     else for (int i = 1; i <= 4; i++) {
     6         int vx = x + cx[i], vy = y + cy[i];
     7         if (a[vx][vy] == 0) DFS(vx, vy, p + 1);
     8     }
     9     a[x][y] = 0;
    10 }

    DFS 的过程绝对是对递归思想最好的诠释,整个搜索框架完全是用递归实现的,这里给出的是 0-1 矩阵走迷宫代码只是其中一种。

    ② 树结构的构建与遍历(请参见:7.3  树与二叉树

    ③ 归并排序(请参见:2.4 排序十讲 中的归并排序部分)

    ④ 最大公约数(请参见:6.4.1 素数与最大公约数

    1 int gcd(int x, int y) {
    2     return y ? gcd(y, x % y) : x; 
    3 }

    ⑤ 线段树的区间询问操作(请参见:<施工中>)

    1 int quem(int o, int l, int r) {
    2     if (t[o].f) push(o, r - l + 1);
    3     if (ql <= l && r <= qr) return t[o].v;
    4     int m = (l + r) >> 1;
    5     return (ql <= m ? quem(ls, l, m) : 0) + (qr >= m + 1 ? quem(rs, m + 1, r) : 0);
    6 }

    因为线段树本身就是树结构,所以其实它也可以归类于②。

    2、分治

    其实分治是递归中的一种,同样用一张图来体现它的特点:

    相较于非分治的递归,分治的特点在于:

    ① 对于每一层向内并不是只递归一次,一般是两次,但更多也可以;

    ② 对于任何元素,其在递归过程中只会被访问一次。

    在递归部分给出的若干份代码中,线段树的区间询问函数归并排序都属于分治思想。

    分治思想的核心在于:分解,解决,合并

    因为同样是一种思想,所以这里也不作更多的解释,参见各种算法对于理解可能会来得更直接一点。

  • 相关阅读:
    还是java中的编码问题
    java restful api
    编码方式
    LinkedHash
    Zoj 2562 More Divisors (反素数)
    spark复习总结03
    spark复习总结02
    spark复习总结01
    使用二进制解决一个字段代表多个状态的问题
    spark性能调优05-troubleshooting处理
  • 原文地址:https://www.cnblogs.com/jinkun113/p/12797469.html
Copyright © 2020-2023  润新知