Java学习Day4|递归和for循环区别,递归相关练习题

1.递归和for循环的区别

1.1 区别

循环能做的事情,递归也能做。但是递归能做的事情,循环不一定可以。
递归操作需要频繁地压栈弹栈,需要消耗大量内存资源,效率较低。

1.2 程序示例

public static void main(String[] args){
		int num = 20;
		long i1 = System.nanoTime();//纳秒级
		int result1 = test1(num);
		System.out.println(result1);
		long i2 = System.nanoTime();
		long i3 = System.nanoTime();
		int result2 = test2(num);
		System.out.println(result2);
		long i4 = System.nanoTime();
    	long time1 = i2 - i1;
		long time2 = i4 - i3;
		System.out.println("使用递归所需执行时间:" + time1 + " 使用for循环所需执行时间:" + time2);
	}
	//使用递归计算斐波那契数列的第n位
	public static int test1(int num){
		if(num == 1 || num == 2){
			return 1;
		}
		return test1(num - 1) + test1(num - 2);
	}
	//使用for循环计算斐波那契数列的第n位
	public static int test2(int num){
		int a = 1;//第n-2位
		int b = 1;//第n-1位
		int c = 1;//第n位
		if(num == 1 || num == 2){
			return 1;
		}
		for(int i = 3; i <= num; i++){
			c = a + b;
			a = b;
			b = c;
		}
		return c;
	}
//输出结果:
//6765
//6765
//使用递归所需执行时间:306800 使用for循环所需执行时间:15300

1.3 总结

输出结果中,两种方式的结果是一样的,但是使用递归所需的执行时间远远超过使用for循环。
这是因为递归操作每次调用方法都需要在JVM栈中压入一个栈帧,多次递归后产生的栈帧数目是极大的,对内存空间产生了很大的要求,并且严重影响了程序执行的效率,所以程序执行的时间会很长,甚至会抛出栈溢出的异常。下图是递归到一定程度时产生栈帧的数目:
Java学习Day4|递归和for循环区别,递归相关练习题_第1张图片
总结:当遇到像树的遍历这种能用递归但是不能使用for循环的问题时,就使用递归,但是当递归和for循环都可以解决问题的时候,最好采用for循环。

2.递归相关练习题

1、递归求N的阶乘
2、递归求1+2+3+…+10
3、按顺序打印一个数字的每一位(例如1234 打印出1 2 3 4)
4、写一个递归方法,输入一个非负整数,返回组成它的数字之和
5、声明一个方法接收一个参数,判断传递的参数值在斐波那契数列的第几位上,如果不存在打印 -1 ,如果存在,打印对应的位数。

public class DiGui {
	public static void main(String[] args){
		System.out.println("第1题:" + jieCheng(10));
		System.out.println("第2题:" + jiaHe(10));
		System.out.print("第3题:");
		printEvery(8848);
		System.out.println();
		System.out.println("第4题:" + numSum(1234));
		System.out.println("第5题:" + feiNum(6765));//6765是第20位
	}
	
	public static int jieCheng(int num){
		return num == 1 ? 1 : num * jieCheng(num - 1);
	}
	
	public static int jiaHe(int num){
		return num == 1 ? 1 : num + jiaHe(num - 1);
	}
	
	public static void printEvery(int num){
		int bi = num % 10;
		if(num / 10 == 0){
			System.out.print(bi + " ");
			return;
		}
		printEvery(num / 10);
		System.out.print(bi + " ");
		return;
	}
	
	public static int numSum(int num){
		if(num / 10 == 0){
			return num;
		}
		return num % 10 + numSum(num / 10);
	}
	
	public static int feiNum(int num){
		//未考虑输入1;
		int a = 1;
		int b = 1;
		int c = 1;
		int count = 2;
		while(c <= num){
			c = a + b;
			a = b;
			b = c;
			count++;
			if(c == num){
				return count;
			}
		}
		return -1;
	}
}

//输出结果
//第1题:3628800
//第2题:55
//第3题:8 8 4 8 
//第4题:10
//第5题:20

6、给出一个整数,判断该数是否为质数
使用pow的时候出现了错误,参数列表写为(num, 1/2),由于整数相除,得到的结果均为num的零次方即1。

public class ZhiShu {
	public static void main(String[] args){
		Scanner sc = new Scanner(System.in);
		int num = sc.nextInt();
		System.out.println(zhiShu(num));
	}
	public static boolean zhiShu(int num){
		if(num == 1){
			return true;
		}
		for(int i = 2; i <= Math.pow(num, 0.5); i++){
			if(num % i == 0){
				return true;
			}
		}
		return false; 
	}
}

如有错误或不足之处,敬请指正。

你可能感兴趣的:(不易,Java基础知识,java)