前言:
本博客前面介绍了不少跟递归的思想相关的例子,比如“汉诺塔”,“八皇后”等。因最近又回忆起“尾递归”,故本文通过2个例子再跟大伙儿探讨一下尾递归。。。
什么是尾递归:
当递归调用是整个函数体中最后执行的语句且它的返回值不属于表达式的一部分时,这个递归调用就是尾递归。
- 递归实例一:
求阶乘!
1 package com.gdufe.recure; 2 3 import java.util.Scanner; 4 5 public class Factorial { 6 7 /** 8 * @param args 9 */ 10 public static void main(String[] args) { 11 Scanner input = new Scanner(System.in); 12 System.out.println("Please input a integer below 15 to be tested:"); 13 while(input.hasNext()){ 14 int num = input.nextInt(); 15 System.out.println(fac(num)); 16 } 17 } 18 /* 19 * 利用数组迭代进行求解 20 */ 21 public static int fac1(int x){ 22 int[] arr = new int[15]; 23 arr[1]=1; 24 for(int i=2;i<15;i++){ 25 arr[i] = i*arr[i-1]; 26 } 27 return arr[x]; 28 } 29 public static int fac2(int n){ 30 return (n==1)?1:n*fac2(n-1); 31 } 32 /* 33 * 阶乘构造尾递归,进行编译优化 34 */ 35 public static int fac(int n){ 36 return fac(n,1); 37 } 38 public static int fac(int n,int result){ 39 if(n==1){ 40 return result; 41 }else{ 42 return fac(n-1,n*result); 43 } 44 } 45 46 }
测试输出:
Please input a integer below 15 to be tested:
3
6
11
39916800
10
3628800
- 递归实例二:
判断回文串!
1 package com.gdufe.recure; 2 3 import java.util.Scanner; 4 5 public class Palindrome { 6 7 /** 8 * @param args 9 */ 10 public static void main(String[] args) { 11 Scanner input = new Scanner(System.in); 12 while (input.hasNext()) { 13 String s = input.next(); 14 System.out.println(s + " is a palidrome string right?" 15 + isPalindrome3(s)); 16 } 17 } 18 19 /* 20 * 构造尾递归 21 */ 22 public static boolean isPalindrome3(String str) { 23 return isPalindrome3(str, 0, str.length() - 1); 24 } 25 26 private static boolean isPalindrome3(String str, int begin, int end) { 27 if (begin >= end) { 28 return true; 29 } else if (str.charAt(begin) != str.charAt(end)) { 30 return false; 31 } else { 32 return isPalindrome3(str, begin + 1, end - 1); 33 } 34 } 35 36 public static boolean isPalindrome2(String str) { 37 if (str.length() <= 1) { 38 return true; 39 } else if (str.charAt(0) != str.charAt(str.length() - 1)) { 40 return false; 41 } else { 42 return isPalindrome2(str.substring(1, str.length() - 1)); //生成子串再重新调用! 43 } 44 45 } 46 /* 47 * 回文串非递归判断 48 */ 49 public static boolean isPalindrome1(String str) { 50 int len = str.length(); 51 for (int i = 0; i < len / 2; i++) { //检查一半即可,不需要全部遍历 52 if (str.charAt(i) != str.charAt(len - 1 - i)) { 53 return false; 54 } 55 } 56 return true; 57 } 58 }
测试输出:
aab
aab is a palidrome string right?false
bbabb
bbabb is a palidrome string right?true
000111111111000
000111111111000 is a palidrome string right?true
尾递归的意义:
从以上尾递归的实现过程当中我们可以发现,回归过程中不用做任何操作(运算),这样的一种特性使得在执行尾递归的过程时,能够被某些特定编译器进行优化,减少内存空间的消耗。