递归算法浅谈

递归算法浅谈

大家好,又见面了,我是全栈君,祝每个程序员都可以多学几门语言。

递归算法

  程序调用自身的编程技巧称为递归( recursion)。
  一个过程或函数在其定义或说明中又直接或间接调用自身的一种方法,它通常把一个大型复杂的问题层层转化为一个与原问题类似的规模较小的问题来求解,递归策略仅仅需少量的程序就可描写叙述出解题过程所须要的多次反复计算,大大地降低了程序的代码量。
   注意:
   (1) 递归就是在过程或函数里调用自身;
   (2) 在使用递增归策略时,必须有一个明白的递归结束条件,称为递归出口。

  一个比較经典的描写叙述是老和尚讲故事,他说从前有座山,山上有座庙,庙里有个老和尚在讲故事,他说从前有座山,山上有座庙,庙里有个老和尚在讲故事,他说从前有座山, ……。这样没完没了地重复讲故事,直到最后老和尚烦了停下来为止。

  重复讲故事能够看成是重复调用自身,但假设不能停下来那就没有意义了,所以终于还要能停下来。递归的关键在于找出递归方程式和递归终止条件。即老和尚重复讲故事这种递归方程式要有,最后老和尚烦了停下来这种递归的终止条件也要有。

阶乘的算法能够定义成函数

递归算法浅谈

当 n>0时,用 f(n-1)来定义 f(n),用 f(n-1-1)来定义 f(n-1)……,这是对递归形式的描写叙述。

当 n=0时, f(n)=1,这是递归结束的条件。

事实上全部的递归问题都能够看成是阶层问题

所要解决的整个问题(整个递归函数)看成是 f(n).在这个递归函数中要做到例如以下几点:

  *1.写出递归的出口
  *2.解决当前要解决的问题—–相当与阶层问题中的(n)
  *3.递归下去(调用自身)解决同样的但规模要小的又一问题—–相当于f(n-1)

假设函数实现了这几点,那么递归算法也就基本成功.

只是有些问题他的f(n-1)可能要调用几次(可能每次的參数还不同),由于他在实现(n)的时候要先调用f(n-1)为前提,

这种样例非常多.比方梵塔问题就是这种情况.

总而言之,你要懂的把复杂的递归问题迁移成简单的阶层递归问题,这时候问题就比較好理解和解决.

以下是几个用递归解决这个问题的几个样例

一.用递归的算法把数组中的N个数按颠倒的次序又一次存放。

经过上面的方法来分析得出程序例如以下:

package sf.digui;

public class Recursion{
 private int b[]=null;
 private int len=0;
 public Recursion(int b[]){
  this.b=b;
  this.len=b.length;
  }
  
  public void resevert(int i,int j){
   if(i>=j) return;
   //====================
   b[i]=b[i]+b[j];
   b[j]=b[i]-b[j];//注意:这里没有通过第三方(另开内存)来实现两个变量的值交换
   b[i]=b[i]-b[j];
   //=========================
   
   resevert(i+1,j-1);
   }
   
   public void printThis(){
    
    for(int i=0;i<len;i++){
     System.out.print(b[i]+” “);
     
     }
     System.out.println();
    }
    
    
    public static void main(String[] args){
     int b[]={1,2,3,4,5,6,7,8,9};
     int len=b.length;
     Recursion rec=new Recursion(b);
     System.out.println(“数组起始的数为:”);
     rec.printThis();
     rec.resevert(0,len-1);
     System.out.println(“数组经过倒转之后的数为:”);
     rec.printThis();
     }
 }

二..用递归算法完毕:有52张牌,使它们所有正面朝上,第一轮是从第2张開始,凡是2的倍数位置上的牌翻成正面朝下;第二轮从第3张牌開始,凡是3的倍数位置上的牌,正面朝上的翻成正面朝下,正面朝下的翻成正面朝上;第三轮从第4张牌開始,凡是4的倍数位置上的牌按上面同样规则翻转,以此类推,直到第一张要翻的牌超过52为止。统计最后有几张牌正面朝上,以及它们的位置号。

经过上面的方法分析,得出程序例如以下:

package sf.digui;

public class DiGui{
 private int n;
 //private int a;
 private int p[]=null;//存放全部牌的正反面信息
 public DiGui(int n){
  this.n=n;
  //a=n;
  p=new int[n];
  for(int i=0;i<n;i++){
   p[i]=0;//这里0表示是正面,1表示是反面
   }
  }
  
  
  public void process(int a){//======相当于f(n)
   int b=a;
   if(a==1) return;// 递归的出口
  //以下部分为解决当前要做的(能够从最后一步或第一步着手思考要做的事)—相当与(n)
  //===================================================    
    while(b<=n){//
     p[b-1]=(p[b-1]==0)?1:0;//
     b=2*b;//
     }
  //====================================================  
    process(a-1);//调用自身,解决同样的但规模要小的又一问题—相当于f(n-1)
    
    
   }
   
   public void printThis(){
    process(n);
    for(int i=0;i<n;i++){
     System.out.println(“第”+(i+1)+”张的正反面序号为:”+p[i]);
     }
    }
    
    
    public static void main(String[] args){
     DiGui digui=new DiGui(52);
     digui.printThis();
     }
 }
 
 
 /*说明:
  *我觉得全部递归都可看成像阶层一样的问题—相当于f(n)=n+f(n-1),都要做递归函数中
  *解决例如以下几个问题:
  *1.写出递归的出口
  *2.解决当前要解决的问题—–相当与阶层问题中的(n)
  *3.递归下去(调用自身)解决同样的但规模要小的又一问题—–相当于f(n-1)
  *
  *
  *要学会把复杂的递归问题迁移成像阶层一样简单的递归问题

  **/

 

以上是我学习递归的一些想法,希望有很多其它人回复,大家一起来谈论,交流,共同进步.

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/118547.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • PHP如何解决网站大流量与高并发的问题(四)「建议收藏」

    PHP如何解决网站大流量与高并发的问题(四)

  • tomcat是否有必要配置环境变量[通俗易懂]

    tomcat是否有必要配置环境变量[通俗易懂]答案:否好多环境都需要配置环境变量,有时候都搞不清楚哪些需要哪些不需要,今天特地查了一下tomcat是否需要配置环境变量。又涨知识了,原来可以配置也可以不配置。既然能不配置,本着懒懒的毛病,当然是不配置了哈哈…但这里还是说明一下为啥不需要配置吧!1、Tomcat解压完成后,直接在bin目录下运行startup.bat,是可以启动Tomcat的!2、但是如果不是在bin目录下运行star…

  • 关于引用mshtml的问题[通俗易懂]

    今天看了个验证码识别的代码,其中引用到了mshtml.dll,找了半天原来就是microsoft.mshtml.dll。查这个dll的时候还发现了好几篇关于这个dll添加问题的文章。顺便看了下,原来这个dll有三个,添加引用时要注意了。   第一篇文章:   1.添加引用的问题   一般在开发环境下会在三个地方存有microsoft.mshtml.dll文件。所以在添加引用时,也

  • java中的反射

    java中的反射主要介绍以下几方面内容理解Class类理解Java的类加载机制学会使用ClassLoader进行类加载理解反射的机制掌握Constructor、Method、Field类的用法理解并掌

  • leetcode 颜色分类_LEETCODE

    leetcode 颜色分类_LEETCODE给定一个包含红色、白色和蓝色,一共 n 个元素的数组,原地对它们进行排序,使得相同颜色的元素相邻,并按照红色、白色、蓝色顺序排列。此题中,我们使用整数 0、 1 和 2 分别表示红色、白色和蓝色。示例 1:输入:nums = [2,0,2,1,1,0]输出:[0,0,1,1,2,2]示例 2:输入:nums = [2,0,1]输出:[0,1,2]示例 3:输入:nums = [0]输出:[0]示例 4:输入:nums = [1]输出:[1] 提示:n == num

  • 滴滴开源敏捷测试用例管理平台!

    点击上方“全栈程序员社区”,星标公众号 重磅干货,第一时间送达 简介 AgileTC是一套敏捷的测试用例管理平台,具备与xmind等脑图工具一致的操作体验。支持测试用例管理、执行计…

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号