zoukankan      html  css  js  c++  java
  • 递归小记

    在非负集定义一个函数f,满足f(0) = 0 且 f(x) = 2f(x-1) + x^2,可以看出f(1) = 1,f(2) = 6,f(3) = 21,当一个函数用自己来定义时就称为递归函数,java中允许函数递归

    1 public int f(int x){
    2         if(x == 0){
    3             return 0;
    4         }else{
    5             int b = 2*f(x-1)+ x*x; //递归调用
    6             return b;
    7         }
    8     }

    递归是一种循环推理,例如我们想得到f(4)的值,那么第6行要计算2*f(3)+4*4,得到f(3)需要计算2*f(2)+3*3,得到f(2)需要计算2*f(1)+2*2,计算f(1)需要计算2*f(0)+1*1,f(0) = 0是已知基准情况,从而得出结果f(1) = 1,f(2) = 6,f(3) = 21,f(4) = 58,这样的情况就是循环推理。

    递归的基本法则:基准情形,不用递归就可以求解

            不断推进,递归调用总能向着一个基准情形前进

            设计法则,假设所有递归调用都能运行

            合成效益法则,求解一个问题的同一实例时,切勿在不同的递归调用中做重复的工作

    2、实践

    (1)求和:1+2+3+.....+n

    /**
    * 求和,程序实现是从基准情形f(0) =0逆序相加,0+1+2+3+.....+(n-1)+n
    * @param n
    * @return
    */
    public int f1(int n){
    int b = 0;
    if(n == 0 ){
    return 0;
    }else {
    b = n + f1(n-1);
    return b;
    }
    }

    (2)阶乘:n! = n * (n-1) * (n-2) * ...* 1(n>0)

    /**
         * 阶乘,程序实现是从基准情形f(1) =1逆序相乘,1*2*3*4*.....*(n-1)*n
         * @param n
         * @return
         */
        public int f2 (int n){
            int b = 0;
            if( n == 1){
                return 1;
            }else {
                b = n * f2(n-1);
            }
            return b;
        } 

    (3)河内塔问题:

     借助2号杆把1号杆上的珠子转移到3号杆上且顺序不变,一次只能移动一个珠子且大珠子不能在小珠子上面,最少需要移动多少次?

    /**
         * 河内塔问题,最少移动2^n-1次,f3(1) = 1,f(2) = 3,f(3) = 7,f(4) = 15
         * 假如只有1个穿孔圆盘,就需要移动1次。 A→C 1 次
         * 假如只有2个穿孔圆盘,就需要移动3次。A→B, A→C,B→C 3次
         * 假如只有3个穿孔圆盘,这时我们可以将上面的2个圆盘看做是一个整体,也就是将3分解成1+2.来考虑。
       * 如我们将最大的第三个圆盘,取消,只剩2个圆盘,这时借助C柱,移动3次可以让2个圆盘到从A到B柱。再考虑最大的圆盘,移动最大的第三个圆盘到C柱。这时借助A柱,移动3次可以让2个圆盘从B到C柱。就需要移动7次。 * @param n * @param a 1号柱 * @param b 2号柱 * @param c 3号柱 */ public void f3(int n, String a, String b, String c) { if(1 == n) { System.out.println(a + "->" + c); } else{ f3(n-1, a, c, b); System.out.println(a + "->" + c); f3 (n-1, b, a, c); } } public int f3_1(int n){ int b = 0; if(n == 1){ return 1; }else{ b = 2*f3_1(n-1)+1; return b; } }

    (4)斐波那契数列:1、1、2、3、5、8、13、21、……

    /**
    *斐波那契数列,n=1和n=2两种基准情形,n=3开始,后一个数等于前两个数相加的和,f4(3) = f(2) + f(1)
    * @param n
    * @return
    */
    public int f4(int n){
    int b = 0;
    if (n ==1 ){
    return 1;
    }else if(n == 2){
    return 1;
    }else {
    b = f4(n-1)+f4(n-2);
    return b;
    }
    }

    (5)全排列:从n个不同元素中任取m(m≤n)个元素,按照一定的顺序排列起来,叫做从n个不同元素中取出m个元素的一个排列。当m=n时所有的排列情况叫全排列。

            如1,2,3三个元素的全排列为:1,2,3、1,3,2、2,1,3、2,3,1、3,1,2、 3,2,1 

        /**
         * 全排列,对数组中的数进行循环换位,输出
         * @param arr 输入数组
         * @param start 起始位置
         * @param end 结束位置,arr.length-1
         * @return
         */
        public void f5(int[] arr, int start, int end){
            // 递归终止条件
            if (start == end) {
                //循环遍历
                for (int i : arr) {
                    System.out.print(i);
                }
                System.out.println();
                return;
            }
            for (int i = start; i <= end; i++) {
                swap(arr, i, start);
                f5(arr, start + 1, end);
                swap(arr, i, start);
            }
        }
        private  void swap(int[] arr, int i, int j) {
            int tmp = arr[i];
            arr[i] = arr[j];
            arr[j] = tmp;
        }
    
        /**
         *全排列的数量,就是数组长度的阶乘,n=1 num=1,n=2 num=1*2=2,n=3 num =1*2*3=6;n=4 num=1*2*3*4=21.......
         * @param arr
         * @return
         */
        public int f5_1(int[] arr){
            int num = 0;
            num = f5_1_1(arr.length);
            return num;
        }
        public int f5_1_1(int n){
            if(n == 1){
                return 1;
            }else{
                return n * f5_1_1(n-1);
            }
        }
    

      

  • 相关阅读:
    考研_数据结构
    快速排序模板
    nginx设置跳转https
    PHP 构造函数
    js scroll事件
    php获取url中的参数
    js 的cookie问题
    yii2关联表
    sql优化之concat/concat_ws/group_concat
    yii2.0 url美化-apache服务器
  • 原文地址:https://www.cnblogs.com/carblack/p/12814947.html
Copyright © 2011-2022 走看看