Java基础语法(递归练习,快速排序,斐波那契数列)

1 递归思想

1、什么是递归:
字面意思就是信息传递,然后归并。
递归可以大大缩短程序的代码,有意识的使用递归,可以用较短的代码解决一些复杂的问题。甚至有些问题非得使用递归解决不可。

2、递归的思想:
把规模大的、较难解决的问题变成规模较小的、易解决的同一问题。
规模较小的问题又变成规模更小的问题,并且小到一定程度可以直接得出它的解,从而得到原来问题的解。

3、何时用递归,满足一下三点:

  • (1)解决某个问题时,可以把这个问题转化为一个新的问题,但解决方法仍与原问题的解法相同,只是所处理的对象有所不同,这些被处理的对象之间是有规律的,或递增或递减或交换等等;
  • (2)通过转化过程是可以让问题得到解决的;
  • (3)必定要有一个明确的结束递归的条件,否则递归将会无止境地进行下去,直到耗尽系统资源。也就是说必须有要某个终止递归的条件。

4、递归使用:

  • 函数中调用函数自己(可多次调用)。

5、强调注意事项:

  • 因为递归是函数自己调用自己,容易造成无限循环。
  • 必须有要某个终止递归的条件。
  • 能用循环轻松解决的就用循环。

2 求 N 的阶乘

1、阶乘计算规则:

1! = 1
2! = 2 * 1! = 2 * 1
3! = 3 * 2! = 3 * 2 * 1! = 3 * 2 * 1

N! = N * (N - 1)! = N * (N - 1) * (N - 2)! = ...... = N * (N - 1) * (N - 2) * ... * 1

2、通过递归实现 N 的阶乘:Factorial.java

/**
 * @author zc
 * @date 2021/11/25 10:46
 * 通过递归实现 N 的阶乘
 *
 * main(String[] args):主程序入口。
 * facN(int n):函数,递归求 n 的阶乘。
 */
public class Factorial {
    /**
     * 主程序入口
     * @param args 系统参数
     */
    public static void main(String[] args) {
        int n = 4;
        int flag = facN(n);
        if (flag == -1) {
            System.out.println("不符合阶乘计算规则");
        } else {
            System.out.println(n + " 的阶乘为:" + flag);
        }
    }

    /**
     * 函数,递归求 n 的阶乘
     * @param n 阶乘参数
     * @return 返回 n 的阶乘
     */
    public static int facN(int n){
        if (n < 1){
            return -1;
        } else if (n == 1) {
            return 1;
        } else {
            return n * facN(n - 1);
        }
    }
}

3 快速排序

1、快速排序原理:

  • (1)在数组中取一个基准点;
  • (2)然后分别从数组的两端扫描数组,交换数据使基准点左边的数据比基准点小,右边数据比基准点大;
  • (3)确定此时的基准点为第一个分界点,将数组分为两部分;
  • (4)每部分又从每部分的两端开始从第 (1)步开始,一直找完分界点,就排序完了。

2、代码实现:QuickSort.java

import java.util.Arrays;

/**
 * @author zc
 * @date 2021/11/4 16:06
 * 快速排序:QuickSort 
 * 
 * main(String[] args):主函数入口 
 * quickSort(int[] num, int left, int right):方法,递归快速排序 
 * getIndex(int[] num, int left, int right):方法,获取分界点 
 * 
 */
public class QuickSort {

    public static void main(String[] args) {
        int[] num ={5,2,8,3,9,4,7};
        System.out.println("原始数据:" + Arrays.toString(num));
        quickSort(num,0,num.length-1);
        System.out.println("快速排序:" + Arrays.toString(num));
    }

    /**
     * 递归快速排序
     * @param num 整型数组,数据存储容器
     * @param left 排序范围左下标
     * @param right 排序范围右下标
     */
    public static void quickSort(int[] num, int left, int right) {
        if(left > right) {
            return;
        } else {
            // 获取分界点
            int index = getIndex(num,left,right);
            // 递归排左边
            quickSort(num, left,index - 1);
            //递归排右边
            quickSort(num,index + 1, right);
        }
    }

    /**
     * 获取分界点
     * @param num 整型数组,数据存储容器
     * @param left 标志左下标扫描
     * @param right 标志右下标扫描
     * @return 返回分界点
     */
    public static int getIndex(int[] num, int left, int right){
        // 基准点
        int key = num[left];

        while(left < right){
            // 扫描右边,右边的数都比基准点大
            while (num[right] >= key && left < right){
                // 右边下标往左移
                right--;
            }

            // 循环完右边后,此时右边下标 right 的值是比基准点 key 小,或者此时 left = right,交换
            num[left] = num[right];

            // 扫描左边,左边的数都比基准点小
            while (num[left] <= key && left < right){
                // 左边下标往右移
                left++;
            }

            // 循环完左边后,此时左边下标 left 的值是比基准点 key 大,或者此时 left = right,交换
            num[right] = num[left];
        }

        // 基准点交换原值
        num[left] = key;
        // 返回此时分界点 left,此时的 left 左边值都比之小,右边值都比之大
        return left;
    }
}

4 斐波那契数列

1、什么是斐波那契数列?
斐波那契数列(Fibonacci sequence),又称黄金分割数列,因数学家莱昂纳多·斐波那契(Leonardo Fibonacci)以兔子繁殖为例子而引入,故又称为“兔子数列”。

指的是这样一个数列:0、1、1、2、3、5、8、13、21、34、55、89……
这个数列从第3项开始,每一项都等于前两项之和。

在数学上,斐波那契数列以如下被以递推的方法定义:

  • F(0) = 0;
  • F(1) = 1;
  • F(n) = F(n - 1) + F(n - 2)(n ≥ 2,n ∈ N*)。

2、斐波那契数列算法:

  • (1) 循环:输出第N个位置的元素;
  • (2) 递归:输出第N个位置的元素。

4.1 循环:FiboFor.java

/**
 * @author zc
 * @date 2021/11/25 10:06
 * 斐波那契数列:
 *      循环:输出第N个位置的元素。
 * mian(String[] args):主程序入口。
 * fibo(int n):函数,循环求斐波那契数列第 N 个位置的元素。
 */
public class FiboFor {
    /**
     * 主程序入口
     * @param args 系统参数
     */
    public static void main(String[] args) {
        int n = 9;
        int flag = fibo(n);
        if (flag == -1) {
            System.out.println("斐波纳契数列给出的位置错误!!!!");
        } else {
            System.out.println("斐波纳契数列第 " + n + " 个位置的元素是:" + flag);
        }
    }

    /**
     * 函数,循环求斐波那契数列第 N 个位置的元素
     * @param n 斐波那契数列第 N 个位置
     * @return 返回斐波那契数列第 N 个位置的元素
     */
    public static int fibo(int n){
        if (n < 0){
            return -1;
        } else if (n == 0){
            return 0;
        } else if (n == 1){
            return 1;
        } else {
            int n0 = 0, n1 = 1, sum = 0;
            for (int i = 2; i <= n; i++) {
                // sum 为 ni 的值
                sum = n0 + n1;
                // 数列向前移动一位
                n0 = n1;
                n1 = sum;
            }
            return sum;
        }
    }
}

4.2 递归:FiboRecursion.java

/**
 * @author zc
 * @date 2021/11/25 10:27
 * 斐波那契数列:
 *      递归:输出第N个位置的元素。
 * mian(String[] args):主程序入口。
 * fibo(int n):函数,递归求斐波那契数列第 N 个位置的元素。
 */
public class FiboRecursion {
    /**
     * 主程序入口
     * @param args 系统参数
     */
    public static void main(String[] args) {
        int n = 10;
        int flag = fibo(n);
        if (flag == -1) {
            System.out.println("斐波纳契数列给出的位置错误!!!!");
        } else {
            System.out.println("斐波纳契数列第 " + n + " 个位置的元素是:" + flag);
        }
    }

    /**
     * 函数,递归求斐波那契数列第 N 个位置的元素
     * @param n 斐波那契数列第 N 个位置
     * @return 返回斐波那契数列第 N 个位置的元素
     */
    private static int fibo(int n) {
        if (n < 0) {
            return -1;
        } else if (n == 0) {
            return 0;
        } else if (n == 1){
            return 1;
        } else {
            return fibo(n - 1) + fibo( n - 2);
        }
    }

}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值