Java算法:递归

函数自己调用自己,方法自己调用自己

确定能否使用递归求解

推导出父问题和子问题的关系,以及递归的结束条件

注:

  • 深入到最里层叫递
  • 从最里层出来叫归
  • 在递的过程中,外层函数的局部变量(以及方法参数)并未消失,归的时候还可以用

1.阶乘

java 复制代码
package algorithm.datastructure.recursion;

public class Factorial {
    public static int factorial(int n){
        if (n == 1){
            return 1;
        }
        return n * factorial(n-1);
    }

    public static void main(String[] args){
        int res = factorial(5);
        System.out.println(res);
    }
}

2.反向输出字符串

java 复制代码
package algorithm.datastructure.recursion;

public class ReversePrintString {
    public static void reversePrint(String str, int n){
        if (n == str.length()) {
            return;
        }
        reversePrint(str, n+1);
        System.out.println(str.charAt(n)); // 在归的过程中打印字符
    }

    public static void main(String[] args){
        reversePrint("Hello World",0);
    }
}
java 复制代码
package algorithm.datastructure.recursion;

public class ReversePrintString {
    public static void reversePrint(String str, int n){
        if (n == -1){
            return;
        }
        System.out.println(str.charAt(n)); // 在递的过程打印字符
        reversePrint(str, n - 1);
    }
    public static void main(String[] args){
        String str = "Hello World";
        reversePrint(str,str.length() - 1);
    }
}

3.递归实现二分查找

java 复制代码
package algorithm.datastructure.recursion;

public class RecursionBinarySearch {
    public static int binarySearch(int[] arr, int target, int lo, int hi){
        if (lo > hi){
            return -1;
        }
        int mid = (lo + hi) >>> 1;
        if (target < arr[mid]){
            return binarySearch(arr, target, lo, mid - 1);
        } else if (arr[mid] < target){
            return binarySearch(arr, target, mid + 1, hi);
        } else {
            return mid;
        }
    }

    public static void main(String[] args){
        int[] arr = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
        System.out.println(binarySearch(arr, 8, 0, arr.length - 1));
    }
}

4.递归实现冒泡排序

循环版本:

java 复制代码
public class Main {
    public static void main(String[] args) {
        Scanner scan = new Scanner(System.in);
        int[] arr = new int[n];
        for(int i = 0; i < n; i++){
            arr[i] = scan.nextInt();
        }
        scan.close();
        
        bubbleSort(arr);

        for(int i = 0; i < arr.length; i++){
            System.out.print(arr[i] + " ");
        }
    }

    public static void bubbleSort(int[] arr){
        int n = arr.length;
        for(int i = 0; i < n - 1 ; i++){
            for(int j = 0; j < n - 1 - i; j++){
                if(arr[j] > arr[j + 1]){
                    int temp = arr[j + 1];
                    arr[j + 1] = arr[j];
                    arr[j] = temp;
                }
            }
        }
    }
}

递归版本:

java 复制代码
package algorithm.datastructure.recursion;

public class RecursionBubbleSort {
    public static void bubbleSort(int[] arr, int n){
        if(n == 0){
            return; // 如果未排序的元素个数为0,则表示已经排好序了
        }
        for(int i = 0; i < n; i++){
            if(arr[i] > arr[i + 1]){
                int temp = arr[i+1];
                arr[i + 1] = arr[i];
                arr[i] = temp;
            }
        }
        bubbleSort(arr, n - 1); // 递, 每次比较后,未排序的元素个数减1
    }

    public static void main(String[] args){
        int[] arr = {5, 4, 3, 2, 1};
        bubbleSort(arr, arr.length - 1);
        for(int e: arr){
            System.out.print(e + " ");
        }
    }
}

改进的递归版本1:

java 复制代码
package algorithm.datastructure.recursion;

public class RecursionBubbleSort {
    public static void bubbleSort(int[] arr, int n){
        if(n == 0){
            return;
        }
        boolean flag = false;
        for(int i = 0; i < n; i++){
            if(arr[i] > arr[i + 1]){
                flag = true;
                int temp = arr[i+1];
                arr[i + 1] = arr[i];
                arr[i] = temp;
            }
        }
        if(!flag){
            return; // 若没有发生交换,则说明数组已经有序,递归结束 注意:Java中没有"全局变量"这个概念
        }
        bubbleSort(arr, n - 1); // 递, 每次比较后,未排序的元素个数减1
    }

    public static void main(String[] args){
        int[] arr = {5, 4, 3, 2, 1};
        bubbleSort(arr, arr.length - 1);
        for(int e: arr){
            System.out.print(e + " ");
        }
    }
}

Java变量作用域规则:

  • 局部变量:在方法内声明,只能在该方法内访问
  • 实例变量:在类中声明,在对象的所有方法中可访问
  • 类变量:用 static 修饰,在整个类中可访问

改进的递归版本2:

java 复制代码
package algorithm.datastructure.recursion;

public class RecursionBubbleSort {
    public static void bubbleSort(int[] arr, int n) {
        if (n == 0) {
            return;
        }
        int x = 0;
        for (int i = 0; i < n; i++) {
            if (arr[i] > arr[i + 1]) {
                int temp = arr[i + 1];
                arr[i + 1] = arr[i];
                arr[i] = temp;
                x = i; // x用来记录每次发生交换时较大元素的位置,一个for循环结束后,x位置后面的元素就是有序的了,因此下次递归时,到x位置结束
            }
        }
        bubbleSort(arr, x); // 但是如果该次for循环没有发生交换,x的值为0,就可以退出递归了
    }

    public static void main(String[] args){
        int[] arr = {5, 4, 3, 2, 1};
        bubbleSort(arr, arr.length - 1);
        for(int e: arr){
            System.out.print(e + " ");
        }
    }
}
相关推荐
暮冬-  Gentle°3 小时前
C++中的命令模式实战
开发语言·c++·算法
卷福同学5 小时前
【养虾日记】Openclaw操作浏览器自动化发文
人工智能·后端·算法
春日见6 小时前
如何入门端到端自动驾驶?
linux·人工智能·算法·机器学习·自动驾驶
图图的点云库6 小时前
高斯滤波实现算法
c++·算法·最小二乘法
一叶落4387 小时前
题目:15. 三数之和
c语言·数据结构·算法·leetcode
老鱼说AI8 小时前
CUDA架构与高性能程序设计:异构数据并行计算
开发语言·c++·人工智能·算法·架构·cuda
罗湖老棍子8 小时前
【例 1】数列操作(信息学奥赛一本通- P1535)
数据结构·算法·树状数组·单点修改 区间查询
big_rabbit05028 小时前
[算法][力扣222]完全二叉树的节点个数
数据结构·算法·leetcode
张李浩9 小时前
Leetcode 15三题之和
算法·leetcode·职场和发展
2301_7938046910 小时前
C++中的适配器模式变体
开发语言·c++·算法