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 + " ");
        }
    }
}
相关推荐
智者知已应修善业1 分钟前
【51单片机8位数码管同时倒计时从9999】2024-1-25
c++·经验分享·笔记·算法·51单片机
洛水水4 分钟前
【力扣100题】86.柱状图中最大的矩形
算法·leetcode·职场和发展
渡之11 分钟前
GRiM-Net 深度解析 | 无人机 GNSS 拒止场景下两阶段跨视角视觉定位框架
深度学习·算法·动态规划·无人机
测试仪器廖生1359025638530 分钟前
罗德与施瓦茨 FSP13频谱分析仪FSP30
网络·人工智能·算法
happymaker062633 分钟前
LeetCodeHot100——560.和为K的子数组
算法
dtq04241 小时前
C语言刷题数组5,6(求平均值,求最大值)
c语言·数据结构·算法
郭梧悠1 小时前
Hash算法入门Hash冲突解决方案
算法·哈希算法
洛水水2 小时前
【力扣100题】81.寻找两个正序数组的中位数
数据结构·算法·leetcode
happymaker06262 小时前
LeetCodeHot100——155.最小栈
算法
洛水水2 小时前
【力扣100题】85.每日温度
算法·leetcode·职场和发展