zoukankan      html  css  js  c++  java
  • 递归函数的使用

    一,概念

            直接或间接地调用自身的算法称为递归算法

              用函数自身给出定义的函数称为递归函数

    二,实例

          实例1阶乘函数

             通过分析可知,要求一个数的阶乘,只要知道它前一位数的阶乘便可求出。 即:n!=n*(n-1)!

      而要求前一位数的阶乘,只要知道它前前一位数的阶乘即可,即:(n-1)!=(n-1)*(n-2)!,因为每次

      计算的方式都相同,所以考虑用递归的方式求解。

            递归关系:f(n)=n*f(n-1)

            递归结束条件:n=1  (因为我们很容易知道1阶乘是1,因此求解其他数的阶乘时,可从1的阶乘开始求起) 

          代码实现

     1 import java.util.*;
     2 public class HW8 {
     3     public static void main(String[] args) {
     4         Scanner in=new Scanner(System.in);
     5         System.out.println("请输入所要求的数值:");
     6         int n=in.nextInt();     //输入所要遍历的数
     7         int number=funtion(n);
     8         System.out.println(n+"的阶乘为:"+number);
     9 
    10     }
    11 
    12     /**
    13      * 求第n个数的阶乘!!!
    14      * @param n 所要求的数的值
    15      * @return  所要求的数的阶乘
    16      * 递归函数结束条件:n<=1
    17      */
    18     private static int funtion(int n) {
    19         if(n==1)      //递归函数的结束条件
    20         {
    21             return 1;
    22         }else{
    23             return n*funtion(n-1);
    24         }
    25 
    26     }
    27 }

     运行结果:

    实例2

        用递归判断一个数组是否是一个递增序列的数组。

     代码实现:

     1 import java.util.*;
     2 public class HW8 {
     3     public static void main(String[] args) {
     4 
     5         int[] arr = new int[20]; //定义一个可存放20个元素的数组
     6         Random rd = new Random();
     7         for (int i = 0; i < arr.length; i++)     //对数组随机赋值
     8         {
     9             arr[i] = rd.nextInt(50) + 1; //范围:1-50
    10         }
    11         System.out.println(Arrays.toString(arr));  //对arr数组进行打印
    12         Arrays.sort(arr);                          //对arr数组进行排序
    13         System.out.println(Arrays.toString(arr));  //对排完序的数组进行打印
    14         boolean flag = funtion(arr);
    15         if (flag) {
    16             System.out.println("该数组是一个有序数组!!!");
    17         } else {
    18             System.out.println("无序数组!!!");
    19         }
    20     }
    21 
    22     /**
    23      * 求该数组是否为一个增序数组
    24      *
    25      * @param arr 所要验证的数组
    26      * @return 增序:true    无或减序:false
    27      */
    28     private static boolean funtion(int[] arr) {
    29         int index = 0;
    30         return funtion2(arr, index);    //因为对数组进行递归时,要让数组的长度不断减小
    31                                         //所以要借助下标
    32     }
    33 
    34     private static boolean funtion2(int[] arr, int index) {
    35         if (index == arr.length - 1) {        //如果数组小标等于数组长度-1,则说明对数组元素遍历完了
    36             return true;                      //且中途没有出现乱序,此时返回true
    37         } else {              
    38             if (arr[index] >arr[index + 1]) {    //出现非增序列,直接返回false
    39                 return false;
    40             } else {
    41                 return funtion2(arr, index+1);   //若前面排序正常,则调用方法继续检测后面的数组元素
    42             }                                           //此时下标+1
    43         }
    44 
    45 
    46     }
    47 
    48 }

     运行结果:

    实例3:

          ( 用递归求解字符串中,字符的个数。)

          通过分析可知,要求解一个字符串str的长度值,首先应知道str.length()-1的值,而要知道str.length()-1的值,

    则要先知道str.length()-2的值,由此不断的递归,可知,知道str-(str.length()-1)的值,即:1,则可求出整个

    字符串的长度。

         递归关系:f(n)=f(n-1)+1

         递归结束条件:index=str.length()-1;   (当下标移动到最后一个下标时,则说明整个字符串已被统计完)

    代码实现:

     1 import java.util.*;
     2 public class HW8 {
     3     public static void main(String[] args) {
     4         Scanner in=new Scanner(System.in);
     5         System.out.println("请输入一个字符串:");
     6         String str=in.nextLine();
     7         int number=count(str);
     8         System.out.println("统计该字符串的长度为:"+number);
     9 
    10     }
    11 
    12     /**
    13      * 求解字符串中,字符的个数。
    14      * @param str 所要求解的字符串
    15      * @return    所统计的字符个数
    16      */
    17     private static int count(String str) {  //将所要求解的字符串传给该方法
    18         int index=0;                   //因为要统计字符串的个数,必须要借助下标
    19         return count2(str,index);  //所以在次调用方法count2
    20     }
    21 
    22     private static int count2(String str, int index) {  
    23         if(index==str.length()-1)     //当下标移动到最后一个位置时,则统计完成
    24         {
    25             return 1;          开始返回,实现“归”
    26         }else{
    27             return count2(str,index+1)+1;  //当下标还没移动到最后一个位置时,该位置的字符串长度为:(比它少一位的字符串段长度)+1
    28         }
    29     }
    30 }

    运行结果:

    实例4用递归实现有序数组的二分搜索)

               通过分析可知,要对一个数组进行二分搜索,首先要求解出该数组中间值,将所查找的数与该

    中间数进行比较,若相等则返回该中间值下标。若小于则将middle-1的值赋给right,将范围进行缩减,

    然后又开始执行上述操作。若大于则将middle+1的值赋给left,将范围进行缩减,然后又开始执行上述操作

     1 import java.util.*;
     2 public class HW8 {
     3     public static void main(String[] args) {
     4         int[] arr = new int[10]; //定义一个可存放10个元素的数组
     5         Scanner in=new Scanner(System.in);
     6         Random rd = new Random();
     7         for (int i = 0; i < arr.length; i++)     //对数组随机赋值
     8         {
     9             arr[i] = rd.nextInt(50) + 1; //范围:1-50
    10         }
    11         System.out.println(Arrays.toString(arr));  //对arr数组进行打印
    12         Arrays.sort(arr);                          //对arr数组进行排序
    13         System.out.println(Arrays.toString(arr));  //对排完序的数组进行打印
    14         System.out.println("请输入所要查找的数:");
    15         int number=in.nextInt();
    16         int index=binarySearch(arr,number,0,arr.length-1);
    17         if (index==-1) {
    18             System.out.println("没有查找到该数!!!");
    19         } else {
    20             System.out.println("所要查找的数为:"+arr[index]+"该数的下标为"+index);
    21         }
    22     }
    23 
    24     /**
    25      *
    26      *用递归实现有序数组的二分搜索
    27      * @param arr 进行搜索的数组
    28      * @number  要查找的数
    29      * @left     开始下标
    30      * @right    结束下标
    31      * @return     若找到返回下标,否则返回-1
    32      *    递归结束条件:left>right
    33      */
    34     private static int binarySearch(int[] arr,int number,int left,int right) {
    35         int middle=(left+right)/2;
    36         if(left>right)       
    37         {
    38             return -1;
    39         }else{
    40             if(arr[middle]==number)
    41             {
    42                 return middle;
    43             }else if(arr[middle]>number)
    44             {
    45                 //right=middle-1;    为简缩代码一般将该语句放在下次调用方法的赋值中
    46                 return binarySearch(arr,number,left,middle-1);
    47             }else{
    48                 //left=middle+1;
    49                 return binarySearch(arr,number,middle+1,right);
    50             }
    51 
    52         }
    53 
    54     }
    55 }

    运行结果:

     递归调用过程:

    实例5:

    用递归解决下面问题:

                                      有三种面值的硬币,分别是1分,2分,5分

                                       现在给出一个价值,例如价值为11,问组成该价值至少需要的硬币数量是多少???

     1 import java.util.*;
     2 public class HW8 {
     3     public static void main(String[] args) {
     4         Scanner in=new Scanner(System.in);
     5         System.out.println("请输入硬币的价值:");
     6         int value=in.nextInt();
     7         int count=fountion(value);
     8         System.out.println("至少需要的硬币数量:"+count);
     9     }
    10 
    11     private static int fountion(int value) {
    12         if(value>=5)
    13         {
    14             return 1+fountion(value-5);
    15         }else if(value<5&&value>=2)
    16         {
    17             return 1+fountion(value-2);
    18         }else if(value>=1&&value<2)
    19         {
    20             return 1;
    21         }else
    22 {
    23 return 0;
    24 }
    24 }
    25 }

    价值      至少需要的硬币数量

        1              1

        2              1

        3              2

       4                2

       5                1

       6                2

      ~                ~


        通过观察可知,当硬币数为1,2,5时只需一枚硬币。当硬币数为3,4时,只需2枚硬币数。

    当大于5时,用价值-5,继续上述循环。。。。

     1 import java.util.*;
     2 public class HW8 {
     3     public static void main(String[] args) {
     4         Scanner in=new Scanner(System.in);
     5         System.out.println("请输入硬币的价值:");
     6         int value=in.nextInt();
     7         int count=fountion(value);
     8         System.out.println("至少需要的硬币数量:"+count);
     9     }
    10 
    11     private static int fountion(int value) {
    12         if(value==1||value==2||value==5)
    13         {
    14             return 1;
    15         }else if(value>2&&value<5)
    16         {
    17             return 2;
    18         }
    19         return 1+fountion(value-5);
    20 
    21     }
    22 }
    
    
    
    
    

     

    实例6:    (汉诺塔问题)

           通过分析可知,对于有n层的汉诺塔问题,可将其看作成两层(上面的i-1层 ,最底1层)来操作,

    首先将上面的i-1层从a借助c移动到b,然后将最底下的一层从a直接移到c,最后将b上的i-1层借助a移动

    到c。而对于如何将i-1层从a移动到b的问题与上述过程类似,所以调用递归来解决。

     1 public class HW8 {
     2     public static void main(String[] args) {
     3     Scanner in=new Scanner(System.in);
     4         System.out.println("请输入汉诺塔的层数:");
     5         int number=in.nextInt();
     6         hanoi(number,'a','b','c');
     7     }
     8 
     9     /**
    10      * 求出有n层汉诺塔时的移动过程
    11      * @param i   汉诺塔的层数
    12      * @param a     起始柱
    13      * @param b     辅助柱
    14      * @param c     目标柱
    15      *              将n层的塔假设成两层,(1层,n-1层)
    16      */
    17     private static void hanoi(int i, char a, char b, char c) {
    18         if(i>1)
    19         {
    20             hanoi(i-1,a,c,b);                  //当为两个时,先将上面的从a移给b (a->b)   [此时有很多,所以要借助b]
    21             System.out.println(a+"->"+c);    //然后将底下的从a移给c (a->c)       [因为此时a上只剩一个,直接移动]
    22             hanoi(i-1,b,a,c);              //然后将b的在移给c   (b->c)       [此时有很多,所以要借助b]
    23                                                //…………此时就完成了一次的移动过程…………//
    24         }else{
    25             System.out.println(a+"->"+c);   //当为一个时,直接将a上的移给c  (a->c)
    26         }
    27 
    28     }
    29 }
  • 相关阅读:
    生成token和获取token
    python异常处理
    获取文件路径
    批量导出和批量安装第三方模块
    python操作从数据库中获取数据的接口
    centos中开机时如何自启动samba服务器
    MSSQL 创建自定义异常
    MSSQL 生成拼音码
    MSSQL FOR MXL PATH 运用(转载)
    MSSQL旋转和反旋转的例子
  • 原文地址:https://www.cnblogs.com/ljl150/p/11589673.html
Copyright © 2011-2022 走看看