递归是编程技术中常用的一种技术,就是方法是支持自己调用自己,在面对过程编程中已经有了递归的接触,像斐波那契序列的求解等这些都是可以用递归来解决的。java方法是支持嵌套调用方法不支持嵌套定义。
使用递归需要注意以下几点:1 递归需要一个基值情况,其意思是导致递归的返回而没有再一次递归调用。2 第一个递归都需要有终止条件。以防止无限递归下去,可能由此引发程序崩溃。以上两点是在递归调用中特别需要注意的两个环节。
使用的递归的情况很多,比如说数学归纳法,数列求和等。接下来使用递归实现单词的全排列。任意给一个单词,输出所有该单词的字母组合。例如输入一个单词有5个字符,那么全排列一共有5*4*3*2*1=120种排列组合。这个可以用递归来实现。
通常如果按照比较直接的想法就是采用分步乘法原理来实现单词全排列。采用for循环方式:例如用户输入四个字符长度的单词,输出所有该单词的字符全排列组合。
public class WholeShowWordNotRecursiveApp {
/**
* @param args
*/
public static void main(String[] args) {
WholeShowWorldNotRecursive a=new WholeShowWorldNotRecursive();
}
}
class WholeShowWorldNotRecursive
{
private char[] arr=new char[100];
private int size=0;
private String s="";
public WholeShowWorldNotRecursive()
{
String s=getString();
size=s.length();
for(int i=0;i<size;i++)
{
arr[i]=s.charAt(i);
}
this.wholeArr(size);
}
public void wholeArr(int wordSize)
{
String temp="";
for(int i=0;i<wordSize;i++)
{
for(int j=0;j<wordSize;j++)
{
for(int k=0;k<wordSize;k++)
{
if(i!=j&&i!=k&&j!=k)
{
temp=arr[i]+""+arr[j]+""+arr[k]+"";
System.out.println(temp);
}
}
}
}
}
public String getString()
{
System.out.println("请输如一个单词:");
InputStreamReader isr=new InputStreamReader(System.in);
BufferedReader br=new BufferedReader(isr);
try
{
s=br.readLine();
} catch (IOException e)
{
e.printStackTrace();
}finally
{
try
{
br.close();
isr.close();
} catch (IOException e)
{
e.printStackTrace();
}
}
return s;
}
}
用户可以输入dsa,则结果显示该单词全排列为:
dsa
das
sda
sad
ads
asd
以上代码虽然能够实现单词全排列,但是面对无法确定长度的单词来说就显得比较麻烦,或者虽然采用多级for循环实现全排列,但效率并不高。采用递归的解决思路如下:
假设这个单词有n个字符,可执行一下步骤:
1 全排列最后边n-1个字母
2 轮换所有n个字符
3 重复以上步骤n次
轮换的意思是所有的字母向左移一位,最左边字符保持不变,会转换到最右边字母的后边。以上步骤可以用下图表示:

以上做法可以使每一个字符都可以移动到第一个。这个过程的可以由以下代码表示:
public static void fullArray(int newSize)
{
if(newSize==1)
return;
for(int i=0;i<newSize;i++)
{
fullArray(newSize-1);
if(newSize==2)
{
showWorld();
}
rotate(newSize);
}
}
public static void rotate(int newsize)
{
int j=0;
int position=size-newsize;
char temp=arr[position];
for(j=position+1;j<size;j++)
{
arr[j-1]=arr[j];
}
arr[j-1]=temp;
}
public static void showWorld()
{
if(count<99)
{
System.out.print(" ");
}
if(count<9)
System.out.print("");
System.out.print(++count+" ");
for(int j=0;j<size;j++)
{
System.out.print(arr[j]);
System.out.print("");
System.out.flush();
}
System.out.print(" ");
if(count%6==0)
{
System.out.println("");
}
}
用户输入tw,全排列为: 1 tw 2 wt
用户输入dsa ,全排列为:1 dsa 2 das 3 sad 4 sda 5 ads 6 asd
用户输入word ,全排列为:
1 word 2 wodr 3 wrdo 4 wrod 5 wdor 6 wdro
7 ordw 8 orwd 9 odwr 10 odrw 11 owrd 12 owdr
13 rdwo 14 rdow 15 rwod 16 rwdo 17 rodw 18 rowd
19 dwor 20 dwro 21 dorw 22 dowr 23 drwo 24 drow
很明显使用递归能够减少代码量,还可以处理任意长度的单词进行全排列。这样的确比上面的for循环灵活。
归于递归的效率
递归虽然在使用中比直接去实现代码功能的要灵活,看起来能够减少代码篇幅,但是在递归过程中会产生栈的额外开销,包括方法地址的返回以及方法参数都要返回到一个内部的栈里面。这与while循环方法执行的速度可能要慢一些,如果递归中需要压栈的参数和地址返回过多就会形成栈溢出现象,不过递归可以简化问题,对于效率递归不是很突出。