蓝桥杯辅导视频学习-递归与循环

递归与循环

一、理论上,任何循环都可以重写为递归形式:
     (1)有时候,为栈限制,需要“尾递归
                            【注】a)递归会进行层层调用,可能会产生栈溢出问题,不同语言对栈的大小都有限制;
                                      b)使用尾递归,可以突破栈的限制,不用每次都压栈。

     (2)java不支持尾递归
    
      有些语言没有循环语句,只能使用递归。

      在C语言中可以使用goto语句来模拟尾递归。


二、循环改成递归
1、关键是发现逻辑“相似性
     递归:直接或间接的调用自身,那么调用者和被调用者之间的应该有着相似性。
     相似性:如  通过循环语句去执行相应功能   <=>  递归在一定条件下调用自身,执行相同功能 。发现在循环过程中的相似性


2、不要忘记递归“出口”

     一个方法去调用它自身,不能是完全相同的环境,否则会进入类似死循环的情况,要通过参数的变化去控制递归的结束。


例子:

蓝桥杯辅导视频学习-递归与循环_第1张图片蓝桥杯辅导视频学习-递归与循环_第2张图片蓝桥杯辅导视频学习-递归与循环_第3张图片


说明:

main()中用for语句、调用fun()、调用fun2()都实现了打印从0~9的功能;调用函数时使用的变量n就是为了控制递归结束的变量;fun2()中使用添加变量,实现不同形式、却有着相同作用的递归。


三、构造相似性

1、如果没有明显的相似性(或无法发现相似性),则需要主动构造其相似性(运用技巧)


2、不能相似的原因很可能是缺少参数(添加参数是主要技巧)


3、递归与数学上的递推公式很类似


例1:计算数组a[] = {2,5,3,9,12,7}中元素的累加和(用递归)

分析:

        递归 <->踢皮球,缓解代码中的逻辑,把复杂的东西推到下一层

        如:求出【. [......]】很多项的和,每个人只求其中最前面的和,剩下那些项的和留给下一层去求和,每层都这样,并把求和结果返回给上一层。

              控制出口的变量:可以利用函数中给出起始位置和结束位置。

        练习用以下三种方式实现本题目:

        1) 、a[begin]+ (begin+1 + ... +结束)

        2)、a[0] + .... + end -1 + a[end]

        3)、折半求和  mid = (begin + end) / 2,分两部分求和  [begin,mid) + [mid,end)

蓝桥杯辅导视频学习-递归与循环_第4张图片

方法二与方法一类似;

方法三:因为折半求和我不是很懂.........所以小伙伴路过会的话留言告诉我哦~


例2:判断两个字符串的内容是否相同:(逐字符判断,递归)

分析:

        首先判断长度是否相等,不等直接return false;

        在长度相等条件下,每一层递归判断字符串中的第一个字符是否相等,是则进行下一层递归,否则返回false;判断两个字符串中的一个字符串是否为空串,(因为第一步已经确定了两个字符串的长度是相同的,所以只要判断一个是否为空串即可),若为空串,则两个字符串相同。

 蓝桥杯辅导视频学习-递归与循环_第5张图片                                                                


四、递归调用

1、递归调用仅仅是被调函数恰为主调函数

计算机中 方法A  调用 方法B:计算机通过栈结构,保存A的执行环境,然后去执行B,B结束时,栈中弹出A的数据,则A继续往下执行。

调用栈:调用函数时需要保存主调函数的一些环境信息。


2、注意每次调用的层次不同

fun(int n = 9)   //调用下一层n=8时已经把n=9压入栈中

...fun(int n = 8){

   ...fun(int n = 7){

      ...fun(int n = 6){

             .......打印6

         }打印7

       }打印8

   }打印9


3、注意每次分配形参并非同一个变量

4、注意返回的次序


总结:要通过多训练,加深自己对递归的理解。

PS:本人初学,初次使用博客记笔记,有不正确或需要改进的地方还请各位多多指教~~



你可能感兴趣的:(蓝桥杯练习)