一:递归和循环

        递归:程序调用自身的编程技巧称为递归。

        循环:for语句或者for each语句实现。

        递归是我们初学程序常常接触的小问题。麻雀虽小,可是深入理解它还是大有学问。

        比如,请用程序计算 n!。首先我们应该先要知道 n!是什么;如 5!=5 * 4 * 3 * 2 * 1,3!= 3 * 2 * 1等等。按照上面的思路,n!= n * (n-1) * (n-2) * (n-3) * (n-4) *.....* 3 * 2 * 1;我们最直白的思想是非递归运用for循环进行阶乘进行求解。

import java.util.Scanner;

public class Resursion01 {
	public static void main(String[] args) {
		System.out.println("请输入您想阶乘的数:");
		Scanner sc1 = new Scanner(System.in);
		int n = sc1.nextInt();
		if(n < 0){
			System.out.println("对不起您输入的数不合法!");
			return;
		}
		int sum = 1;
		for(int i = n; i > 0; i--){
			sum *= i;
		}
		System.out.println(n+"! = "+sum);
	}
}

        上面的程序时间复杂度为O(n);空间复杂度比较小。(注:因为sum定义为int型,故进行阶乘的数不要太大,容易溢出)

        本节程序讲的是递归,我们当然要用递归去解决一下这个问题。递归就是自己调用自己,但是有判断条件,并且当判断量大于终止条件就一直向下递归,当不满足终止条件时,它就向上递归返回值。最终给出我们想要的结果。故运用递归进行阶乘的代码为:

import java.util.Scanner;

public class Resursion02 {

	public static void main(String[] args) {
		System.out.println("请输入向进行阶乘的数N:");
		Scanner sc = new Scanner(System.in);
		int n = sc.nextInt();
		if(n < 0){
			System.out.println("输入的N不合法.");
			return ;
		}
		int sum = f(n);
		System.out.println(sum);
	}
	
	public static int f(int n){
		
		if(n == 1){
			return 1;
		}else{
			return n * f(n-1); 
		}
	}
}

        这个程序的空间复杂度和时间复杂度都很大,所以我们在运用递归时一定要注意。(注:因为sum定义为int型,故进行阶乘的数不要太大,容易溢出)

        n!的阶乘程序递归图为:

java 递归循环菜单 java递归和循环区别_java 递归循环菜单

二:递归和循环分析

        递归的优劣

        递归的优势:递归的程序代码简单易读,在实现某些算法时还是有特定的优势:比如用递归实现数据结构中的Tree遍历前序遍历(先遍历根节点,再遍历左子树,最后遍历右子树)、中序遍历(先遍历左子树,再遍历根节点,最后遍历右子树)、后续遍历(先遍历左子树,再遍历右子树,最后遍历根节点);

        递归的劣势:递归是程序本身调用自身,函数调用自身是有时间和空间消耗的(栈空间的消耗),在递归每一次调用自身这个函数时,都需要在内存中分配一定的空间以保存参数、临时变量以及返回地址等信息,而在栈中数据的出栈和入栈都是有时间需求的,故运用递归时会大大降低程序的运行效率,尤其是当递归基数比较大时,效率尤为明显,故在一般的开发中不会运用递归。

        循环的优劣:优势,重复执行一些步骤,执行完的就释放空间,一直到一个终止条件,故循环的空间复杂度比较低一些。