递归与分治

作者: 阁下_3258 | 来源:发表于2022-07-20 08:38 被阅读0次

一、分治

分治( Divide-and-Conquer )及分而治之,就是把一个较为复杂的问题分成多个规模较小但结构和原问题相同的或相似的子问题,然后在分别解决这些子问题,最后再将这些子问题合并即可得到原问题的解。在计算机中分治是一种很重要的算法思路,如:快速排序、归并排序……都是建立在分治的思路上。

根据上面定义分治可以分为三个步骤:

  1. 分解:将原问题分解为若干个和原题结构相同或相似的子问题。
  2. 解决:递归所有问题,如果问题小到可以直接解决则直接解决它,若不能直接解决则继续分解。
  3. 合并:将所有子问题的解进行合并以求出原问题的解。

:分治分解出的的问题应该是相互独立的、没有交叉的,如果分解的问题有相交的地方,那么改题则不能使用分治解决。一般来说分治作为一种算法思想既可以使用递归的手段来实现,也可以通过非递归的方式来实现,不过一般来说使用递归实现分治较为简单(从广义上将,分治分解的问题个数>0即可,但是严格来讲一般把子问题个数为1的的情况成为减治

二、递归

递归(递去归来):就是在函数(或方法)运行的过程中自己调用自己的现象。 在《算法笔记》上提到的递归的定义:“要理解递归,你首先要理解递归,直达你能理解递归”,这应该算是对递归有趣且十分直观的解释。递归就在于反复调用自己函数(或方法),但每次把问题规模缩小直到得到边界数据的结果,然后在返回的路上一步步求出最后的解。由此看来递归非常适分治的思想

递归两概念&三要素

两概念:①:递归边界②递归式(递归调用)

三要素

  1. 明确你这个函数(或方法)想要⼲什么,
  2. 寻找递归结束条件,否则肯进入递归死循环。
  3. 提取重复的逻辑,缩小问题规模。

递归缺点

递归相对的不同的循环运行效率略低,在递归调用的过程当中系统为每一层的返回点、局部量等开辟了栈来存储。递归次数过多容易造成栈溢出等。

例1:n的阶乘

分析:n! = n * (n-1),(n-1)! = (n-1) * (n-2)! ,(n-2)! = (n-2) * (n-3)!,(n-3)! = (n-3) * (n-4)!,2! = 2 * 1,1! = 0! = 1

由分析得出递归边界应该是当n==1或n==0当到达边界时返回值应为1同时递归式应为F(n)=n*F(n-1),编写C代码如下:

#include<stdio.h>
int Factorial(int n)
{
    if(n <= 1) //递归边界 
        return 1;
    else
        return Factorial(n - 1) * n ;//递归式 
 }
main()
{
    int n;
    scanf("%d",&n);
    printf("%d",Factorial(n));
}

例2:斐波那契数

斐波那契数列,又称黄金分割数列、因数学家列昂纳多·斐波那契以兔子繁殖为例子而引入,故又称为“兔子数列”,它指的是这样一个数列:1,1,2,3,5,8,13……从这组数可以很明显看出这样一个规律:从第三个数开始,后边一个数一定是在其之前两个数的和。及F(1)=1,F(2)=1,F(n)=F(n-1)+F(n-2)

由上述分析得出递归边界n<=2返回值为1,递归式为F(n-1)+F(n-2),C代码如下

#include<stdio.h>
int Fibonacci(int n)
{
    if(n <= 2) //递归边界 
        return 1;
    return Fibonacci(n-2)+Fibonacci(n-1); //递归式 
}
main()
{
    int n;
    scanf("%d",&n);
    printf("%d",Fibonacci(n));
}

奇特的递归:求 求1+2+…+n

题目描述

求 1+2+…+n1+2+…+n,要求不能使用乘除法、forfor、whilewhile、ifif、elseelse、switchswitch、casecase 等关键字及条件判断语句 (A?B:C)。

数据范围:1 <= n <= 1000

思路:利用短路与运算实现递归边界的跳出

#include<stdio.h>
int getSum(int n) {
    (n>0) && ( n += getSum(n-1) );
    //短路与:首先判断左半部分,若左半部分为真则在执行判断右半部分
    //若左半部分为假,则不执行右半部分
    return n;
}
main()
{
    int n;
    scanf("%d",&n);
    printf("%d",getSum(n));
}

参考内容

  1. 分治_百度百科
  2. 递归(编程技巧)_百度百科
  3. 算法笔记(2016年机械工业出版社出版的图书)
  4. AcWing 84. 求1+2+…+n

相关文章

  • 递归与分治

    1| 棋盘覆盖问题 || 在一个2k x 2k ( 即:2^k x 2^k )个方格组成的棋盘中,恰有一个方格...

  • 递归与分治

    递归与分治 一、斐波那契(Fibonacci)数列的递归实现 他讲的一个故事:如果说兔子在出生两个月后,就有繁殖能...

  • 递归与分治

    递归(Recursion):指函数的定义中调用函数自身的方法。 递归调用过程: 举个很好玩的栗子: 用递归调用输出...

  • 分治与递归

    在刷leetcode的过程中,感觉总结方法是很重要的,因为很多类型一样的题目,采用的完全是同样的算法,今天要说的这...

  • 递归与分治

    一、分治 分治( Divide-and-Conquer )及分而治之,就是把一个较为复杂的问题分成多个规模较小但结...

  • 8.分治、回溯的实现与特性

    前言 分治与回溯,其实本质上就是递归,只不过它是递归的其中一个细分类。你可以认为分治和回溯最后就是一种特殊的递归,...

  • 动态规划

    一、分治,回溯,递归,动态规划 1.1、递归的代码模板 1.2、分治(Divide & Conquer)的代码模板...

  • 分治法与递归

    设计思想与策略 分治法的设计思想是:将一个难以直接解决的大问题,分割成一些规模较小的相同问题,以便各个击破,分而治...

  • 分治、回溯

    分治和回溯本质上都是递归。 分治 Divide & Conquer 在计算机科学中,分治法是建基于多项分支递归的一...

  • 分治策略

    求解递归式方法 最大子数组问题 分治策略 分治法流程 伪代码 C++实现 线性解 流程 代入法求解递归式 递归树法...

网友评论

    本文标题:递归与分治

    本文链接:https://www.haomeiwen.com/subject/mkusirtx.html