算法小白总结(二)------递归调用

来源:互联网 发布:相机软件大全 编辑:程序博客网 时间:2024/06/05 09:41

递归调用:直接/间接调用自身。

  1. 特点:通过栈管理,后调用先返回
  2. 优点:结构清晰,可读性强,易于用数学归纳法证明其正确性
  3. 缺点:效率低,时间长,空间消耗多

消除递归思路:

  • 用户自定义栈 —— 取代—— 系统递归调用工作栈

常见的递归调用

1. n的阶乘  
  /**     * 求n的阶乘     * @param n      * @return  n的阶乘     */    public static double n_factorial(int n){        if(n == 0) return 1;        return n*n_factorial(n-1);    }
2.  Ackerman函数
    /**     * ackerman函数实现     * A(1,0) = 2     * A(0,m) = 1     * A(n,0) = n+2     * A(n,m) = A(A(n-1,m),m-1)     * @param n     * @param m     * @return 返回A(n,m)     */    public static int ackerman(int n, int m) {        if(n==1 && m==0) return 2;        if(n==0) return 1;        if(m==0) return n+2;        return ackerman(ackerman(n-1, m), m-1);    }
3. 排列问题    R = {r1,r2,...,rn}是将要进行排列的n个元素,Ri = R - {ri}。集合X的全排列为perm(X)。(ri)perm(X)表示在全排列perm(X)的前面加上前缀ri的到的排列。    所以R的全排列为:    n = 1;perm(R) = (r)。    n >1 ;perm(R) 由(r1)perm(R1),(r2)perm(R2),.......,(rn)perm(Rn)组成。
/**     * 交换 list数组中第i个元素和第k个元素的值     * @param list     * @param i     * @param k     */    public static void swap(Object []list, int i, int k){        Object mid = list[i];        list[i] = list[k];        list[k] = mid;    }    /**     * 列出数组list 第n个元素到第m的元素的全排列     * @param list     * @param n     * @param m     */    public static void prem(Object []list, int n, int m) {        if(n == m){            for(int i=0; i<=m; i++)                System.out.print(list[i]);            System.out.println();        }else{            for(int i=n; i<=m; i++){                swap(list,n,i);                prem(list, n+1, m);                swap(list, n, i);            }        }    }
4. Hanoi问题
    private static int i =1;    //记录移动次数    /**     * 输出 a--->b     * @param a     * @param b     */    public static void move(char a, char b) {        System.out.println(a + "--->" + b);    }    /**     * 将n个盘从a塔座搬运到b塔座,借助c塔座     * @param n     * @param a     * @param b     * @param c     */    public static void hanoi(int n, char a, char b, char c) {        if (n > 0) {            hanoi(n - 1, a, c, b);            System.out.print("第"+i+"次:");            move(a, b);            i++;            hanoi(n - 1, c, b, a);        }    }
0 0