欢迎访问宙启技术站
智能推送

Java中的递归函数及实现方式

发布时间:2023-05-22 08:00:27

一、递归函数介绍

递归是指函数直接或间接调用自身的函数过程,在计算机程序中广泛应用。递归函数是指调用了自身的函数,通常分为两种情况。一种是在函数内部调用本身的函数,称为直接递归;另一种是在函数内部调用另一个函数,而该函数又调用了其本身的函数,称为间接递归。

二、递归的实现方式

递归的实现方式有两种:递归算法和递归函数。递归算法是指使用递归方式编写的算法,递归函数是指使用递归方式编写的函数,其实现方式有两种:尾递归和非尾递归。

1. 尾递归

尾递归是指递归函数在调用自身时,该调用语句是函数体中最后一条语句。尾递归相对于非尾递归来说,不会消耗过多的栈空间,而是会不断的覆盖当前函数的栈帧,直到递归结束后不再需要返回值时,才会一层层地返回。因此,使用尾递归,可以使得空间复杂度稳定在O(1)。下面是一个尾递归的例子,计算n的阶乘:

//尾递归实现n的阶乘

public static int factorial(int n,int res){

    if(n<=1){

        return res;

    }

    return factorial(n-1,n*res);

}

2. 非尾递归

非尾递归是指递归函数在调用自身时,其调用语句不是函数体中的最后一条语句。非尾递归相对于尾递归来说,会消耗大量的栈空间,极易造成栈溢出,因此需要先将递归拆分为循环。

//非尾递归实现n的阶乘

public static int factorial(int n){

    if(n<=1){

        return 1;

    }

    return n*factorial(n-1);

}

二者的区别在于:尾递归的实现方式相当于将输出通过一直调用本身的函数,逐渐逼近输出,直到输出为止,嵌套深度为1,由于只有一个函数实体,所以不需要额外的栈空间;非尾递归的实现方式相当于由输出倒推计算过程,嵌套深度越深,递归次数越多,使用的栈空间也就越多。

三、递归函数应用场景

递归函数的应用场景很多,比如树的遍历和排序、图的遍历和搜索、回溯法等等。以下是几个递归函数的应用场景:

1. 求斐波那契数列的第n项

斐波那契数列中的 项和第二项都是1,此后每一项都是它前面两项的和,即f(1)=1,f(2)=1,f(n)=f(n-1)+f(n-2)。以下是通过递归函数的方法实现f(n)的代码:

public int fibonacci(int n){

    if(n<1){

        return 0;

    }

    if(n==1 || n==2){

        return 1;

    }

    return f(n-1)+f(n-2);

}

2. 求一个数的阶乘

求一个正整数n的阶乘,即n!=1*2*3*...*n。以下是通过递归函数的方法实现n!的代码:

public int factorial(int n){

    if(n<=1){

        return 1;

    }

    return n*factorial(n-1);

}

3. 二叉树前、中、后序遍历

二叉树的遍历有三种方式: 前序遍历、中序遍历和后序遍历。以下是通过递归函数的方法实现二叉树的前序遍历、中序遍历和后序遍历的代码:

// 前序遍历输出  根->左->右

public void preOrder(TreeNode root){

    if(root != null){

        System.out.print(root.val + " ");

        preOrder(root.left);

        preOrder(root.right);

    }

}

// 中序遍历输出  左->根->右

public void inOrder(TreeNode root){

    if(root != null){

        inOrder(root.left);

        System.out.print(root.val + " ");

        inOrder(root.right);

    }

}

// 后序遍历输出  左->右->根

public void postOrder(TreeNode root){

    if(root != null){

        postOrder(root.left);

        postOrder(root.right);

        System.out.print(root.val + " ");

    }

}

四、递归函数的优缺点

递归函数的优点在于其代码表达式简单易懂,实现方便。通过递归函数的使用,可以提高代码的可读性和可维护性。而递归函数的缺点则在于嵌套层数越多,其堆栈空间的使用量就越大,可能引起栈溢出。因此,在实际开发中,需要根据实际情况来选择使用递归函数还是迭代循环。