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 + " ");
        }
    }
}
相关推荐
启观川8 小时前
数据结构与算法 -第 3 章 常用算法-动态规划
数据结构·笔记·python·算法
码爸8 小时前
排序算法介绍
python·算法·排序算法
动词ing9 小时前
【题目练习】算法 组合总和||
算法
longlongzihan9 小时前
链表找环:Floyd 判圈算法(LeetCode 141 & 142 )
c++·算法·leetcode·链表
专业程序开发源9 小时前
flask家电故障预测系统92491-计算机课程设计/毕业设计
vscode·python·sql·算法·flask·课程设计
Logic1019 小时前
C语言/数据结构欧几里得算法题解:长方形切割最大正方形——贪心划分计数
c语言·数据结构·算法·贪心算法·时间复杂度·空间复杂度·欧几里得算法
yi01110 小时前
LeetCode 643. 子数组最大平均数 I|从暴力枚举到滑动窗口
人工智能·笔记·python·算法·leetcode·滑动窗口
极光通讯10 小时前
服务器内存来料检验(IQC)实操:批次追溯、外观判定与上机验证
java·服务器·算法
淡海水10 小时前
02-04-原理篇-GC Roots与对象图遍历
算法·unity·c#·图·gc·遍历·roots
ClickHouseDB11 小时前
ClickHouse 大规模 OpenTelemetry 数据接入架构的可靠性演进
算法