递归函数的使用

一,概念

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

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

二,实例

      实例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 }
原文地址:https://www.cnblogs.com/ljl150/p/11589673.html