递归算法java map_Java数据结构与算法(第六章递归)

递归是一种方法(函数)调用自己的编程技术。

三角数字

数字序列 1、3、6、10、15、21、。。。。

这个数列中的第n项是由第n-1项加n得到了。

这个序列中数字被称为三角数字,因为他们可以被形象化地表示成对象的一个三角形排列,如图:

使用循环查找第n项

第n项的值,比如说第4项(其值为10)。你会如何设计?

int triangle(int n){

int tatal = 0;

while(n>0){

total = total +n;

--n;

}

return total;

}

c905262e8b536da332a5a6ccd3d1bd3d.png

这个方法循环了n次,total值在第一次循环中加n,在第二次循环中加n-1,如此循环一直到加1,当n减小到0时退出循环。

package com.digui;

import java.io.BufferedReader;

import java.io.IOException;

import java.io.InputStreamReader;

public class Triangle {

static int theNumber;

public static void main(String[] args) throws IOException {

System.out.print("Enter a number: ");

System.out.flush();

theNumber = getInt();

int theAnswer = triangle(theNumber);

System.out.println("Trinagle = "+theAnswer);

}

public static int triangle(int n)throws IOException{

if(n==1){

return 1;

}else{

return (n+triangle(n-1));

}

}

public static String getString() throws IOException{

InputStreamReader isr = new InputStreamReader(System.in);

BufferedReader br = new BufferedReader(isr);

return br.readLine();

}

public static int getInt() throws IOException{

String s = getString();

return Integer.parseInt(s);

}

}

//输入输出:

Enter a number: 2

Trinagle = 3

Enter a number: 1000

Trinagle = 500500

递归方法的特征

所有递归方法都具备的关键特征:

调用自身

当它调用自身的时候,它这样做事为了解决更小的问题。

存在某个足够简单的问题的层次,在这一层算法不需要调用自己就可以直接解答,且返回结果。

在递归算法每次调用自身的过程中,参数变小(也许是被多个参数秒速的范围变小),这反映了问题变小或变简单的事实。当参数或者范围达到一定的最小值时,将会触发一个条件,此时方法不需要调用自身而可以返回。

递归方法有效率吗?

调用一个方法会有一定的额外开销。控制必须从这个调用的位置转移到这个方法的开始处。除此之外,传给这个方法的参数以及这个方法返回的地址都要被压入到一个内部的栈里,为的是这个方法可以访问参数值和知道返回到哪里。

就triangle()这个方法来讲,因为有上述开销二造成的结果,可能while循环方法执行的速度比递归的方法快。

如果由于递归方法的存在,造成了太大规模的方法调用的话,可能会考虑消除递归,。

另外一个低效率反映在系统内存空间存储所有的中间参数以及返回值,如果有大量的数据需要存储,这就会引起栈溢出的问题。

人们常常采用递归,是因为它从概念上简化了问题,而不是因为它本质上更有效率。

数学归纳法

递归程序设计中数学归纳法。数学归纳法是一种通过自身的语汇定义某事物自己的方法。(语汇也被用于描述证明原理的相关方法。)使用归纳法,可以用数学的方式定义三角数字:

tri(n) = 1                if n=1

tri(n)=n+tri(n-1)    if n>1

用自身来定义某事可能看起来是在转圈子,但是事实上它是完全正确的(假设有一个基值情况)。

阶    乘

阶乘在概念上和三角数字类似的,只是用乘法取代了加法而已,得到第n个三角数字是通过n加上n-1个三角数字的和,而n的阶乘则是通过n乘以n-1的阶乘来得到的。

int factorial(int n){

if(n==0){

return 1;

}else{

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

}

}

变 字 位

这是递归应用的另一种情况。

package com.digui.anagram;

import java.io.IOException;

import redis.digui.Triangle;

public class AnagramApp {

static int size;

static int count;

static char[] arrChar = new char[100];

public static void main(String[] args) throws IOException {

System.out.print("Enter a word:");

String intput = Triangle.getString();

size = intput.length();

count = 0;

for (int i = 0; i 

arrChar[i] = intput.charAt(i);

}

doAnagram(size);

}

public static void doAnagram(int newsize){

if(newsize==1)

return;

for (int i = 0; i 

doAnagram(newsize-1);

if(newsize==2)

displayWord();

rotate(newsize);

}

}

private static void displayWord() {

if(count<99)

System.out.print(" ");

if(count<9)

System.out.print(" ");

System.out.print(++count+" ");

for (int i = 0; i 

System.out.print(arrChar[i]);

}

System.out.print(" ");

System.out.flush();

if(count%6==0){

System.out.println("");

}

}

public static void rotate(int newsize){

int j;

int postion = size-newsize;

char temp = arrChar[postion];

for (j = postion+1; j 

arrChar[j-1] = arrChar[j];

}

arrChar[j-1] = temp;

}

}

输入输出:

Enter a word:cats

1 cats   2 cast   3 ctsa   4 ctas   5 csat   6 csta

7 atsc   8 atcs   9 asct  10 astc  11 acts  12 acst

13 tsca  14 tsac  15 tcas  16 tcsa  17 tasc  18 tacs

19 scat  20 scta  21 satc  22 sact  23 stca  24 stac

递归的二分查找

递归取代循环

private int recFind(long key,int lowerBound, int upperBound){

int curIn;

curIn = (lowerBound + uperBound)/2;

if(a[curIn]==key)

return curIn;

else if(lowerBound>upperBound)

return nElems;

else{

if(a[curIn]

return recFind(key,curIn+1,uperBound);

else

return recFind(key,lowerBound,curIn-1);

}

}

归并排序

。。。。。。

。。。。。。

小        结

一个递归的方法每次用不同的参数值反复调用自身。

某种参数值使递归的方法返回,而不再调用自身。这种为基值情况。

当递归方法返回时,递归过程通过逐渐完成各层方法实例的未执行部分,而从最内层返回到最外层的原始调用处。

待续。。。

197

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值