Java数据结构与算法--递归和回溯

什么是递归

任何调用自身的函数成为递归。递归是从跟数学领域借鉴过来的一种有用的技术,递归代码通常比迭代代码更加简洁易懂。

实例

以阶乘喂例,其递归定义如下:

n!=1          n=0

n!=n*(n-1)!     n>0
复制代码

代码实现:

    public static void main(String[] args) {
        int fact = Fact(5);
        System.out.println(fact);
    }
    static int Fact(int n){
        if (n==1){
            return 1;
        }
        if (n==0){
            return 1;
        }
        return n*Fact(n-1);
    }
复制代码

递归可视化

每次递归调用都在内存中生成一个新的函数副本,一旦函数结束,这些副本就从内存中删除。

递归与迭代

递归:

  • 当达到基本情形时,递归终止
  • 每次递归都需要额外的空间用于栈帧开销
  • 如果无穷递归(没有出口),程序会堆栈溢出
  • 某些问题用递归更容易解决

迭代:

  • 当循环条件为假时,迭代终止
  • 每次迭代不需要额外空间
  • 出现死循环后程序会一直循环执行
  • 求解问题可能没有递归那样显而易见

递归算法的经典用例

  • 斐波那契数列、阶乘
  • 归并排序、快速排序
  • 二分查找
  • 树的遍历
  • 图的遍历:深度+广度
  • 动态规划
  • 分治算法
  • 汉诺塔
  • 回溯算法

相关问题

  1. 汉诺塔谜题 算法:
  • 将源柱最上面的n-1个圆盘移动到辅助柱上
  • 将第n个圆盘从源柱移到目的柱。
  • 将辅助柱的n-1个圆盘一刀目的柱
  • 圆柱最上面的n-1个圆盘移动到辅助柱又可以看成一个新问题,然后以同样的方式解决。
    /**
     * @param n 第几个圆盘
     * @param frompeg 源柱
     * @param topeg 目标柱
     * @param auxpeg 辅助柱
     */
    void TowersOfHanoi(int n,char frompeg,char topeg,char auxpeg){
        /**
         * 如果只有一个圆盘,直接移动并返回
         */
        if (n == 1){
            System.out.println("move disk 1 from peg"+frompeg+"to peg"+topeg);
        }
        /**
         * 利用C柱做辅助,将A最上面的n-1个圆盘移动到B
         */
        TowersOfHanoi(n-1,frompeg,auxpeg,topeg);
        /**
         * 将剩下的圆盘从A移动到C
         */
        System.out.println("move disk from peg"+frompeg+"to peg"+topeg);
        /**
         * 利用A做辅助,将B上的n-1个圆盘移动到C
         */
        TowersOfHanoi(n-1,auxpeg,topeg,frompeg);
    }
复制代码
  1. 给定一个数组,用递归方法判定数组中的元素是否是有序的。
    int isArrayInSortedOrder(int[] a,int index){
        if (a.length == 1){
            return 1;
        }
        return a[index-1]<=a[index-2]?0:isArrayInSortedOrder(a,index-1);
    }
复制代码

什么是回溯

回溯是一种采用分治策略进行穷举搜索的方法。

回溯经典用例

  • 二进制串
  • 生成k进制串
  • 背包问题
  • 广义字符串
  • 哈密顿回路
  • 图着色问题

相关问题

  1. 生成所有n位长的字符串。假设A[0..n-1]是一个大小为n的数组。
    static void Binary(int n){
        if (n<1){
            Arrays.stream(A).forEach(s-> System.out.print(s+" "));
        }else {
            A[n - 1] = 0;
            Binary(n - 1);
            A[n - 1] = 1;
            Binary(n - 1);
        }
    }
复制代码

根据问题规模减小和递归求解主定理可以求得时间复杂度为2^n

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值