递归的概念:是指在方法的定义中使用方法自身。也就是说,递归算法是一种直接或者间接调用自身方法的算法。简言之:在定义自身的同时又出现自身的直接或间接调用。
注意:递归必须要有一个退出的条件!!!
下面写一个简单的程序实现一下递归,即:程序自己调用自己。
class Test{
public void add(){
System.out.println ("add");
add2 ();
}
public void add2(){
System.out.println ("add2");
add ();
}
public static void main(String[] args){
Test t = new Test ();
t.add ();
}
}
当程序运行完add块后,进去add2块,结束后又回到add块,由于没有停止条件,所以程序会无限循环,直到栈溢出后停止。
可能你会说这是个循环并不是递归,我们前面说到,递归是需要终止条件的,那么最重要的一点就是一定要把握住出口,也就是做递归算法必须要有一个明确的递归结束条件。这一点是非常重要的。
在递归中,方法结束执行的关键字: return
在运用递归函数时我们要注意:
1: 方法本身调用本身实现递归
2: 方法开始的时候要设置结束的条件,不然会导致栈溢出错误
3: 方法可以加上参数,使用参数作为递归中间的变量控制
4: 条件设置要合理,不然会导致死循环出现栈溢出错误
下面,我们尝试利用上述add和add2递归函数编写一个程序,使他们相互调用,实现从1到100的输出。
package DiGui;
public class Test {
public void add(int n){
if(n > 100){
System.out.println ("n>=100 add:" + n);
return;
}
n++;
System.out.println ("add:" + n);
add2 (n);
}
public void add2(int n){
if(n > 100){
System.out.println ("n>=100 add:" + n);
return;
}
n++;
System.out.println ("add2:" + n);
add (n);
}
public static void main(String[] args){
Test t = new Test ();
t.add (0);
}
}
运行结果为:
在上述代码中添加了结束条件,当add或add2输出大于等于100时,则推出调用,输出当前值。
在此基础上,增加条件就可以实现1+2+3+···+100的运算结果,如下:
package DiGui;
public class Test {
public void add(int n){
if(n > 100){
System.out.println ("n>=100 add:" + n);
return;
}
n++;
System.out.println ("add:" + n);
add2 (n);
}
public void add2(int n){
if(n > 100){
System.out.println ("n>=100 add:" + n);
return;
}
n++;
System.out.println ("add2:" + n);
add (n);
}
//*************0+1+2+3+4+5+....+100********************
public void add3(int n, int count){
if(count > 100){
System.out.println ("count > 100 add3: " + n);
System.out.println (count);
return;
}
System.out.println ("add3: " + n);
n += count;
count++;
add3 (n, count);
}
public static void main(String[] args){
Test t = new Test ();
t.add3 (0, 0);
}
}
结果如下:
同样的方法,添加条件实现1-100偶数相加之和。
//******0-100偶数和*******
//方法一
count += 2 ;
n += count -1;
//方法二
count++;
if(count % 2 == 0) {
n += count;
}
递归还可以绘制图形,如:谢尔宾斯基地毯、谢尔宾斯基三角形等。
下面就用递归的方法绘制谢尔宾斯基地毯。
首先创建一个窗体,设定好初始参数:
public class DrawPadJUXING extends JFrame {
// 创建一个窗体
public DrawPadJUXING(){
setTitle ("递归矩形-谢尔宾斯基地毯");
setSize (800, 800);
setDefaultCloseOperation (EXIT_ON_CLOSE);
setVisible (true);
setLocationRelativeTo (null);
}
@Override
public void paint(Graphics g){
super.paint (g);
// 绘图
drawSheerBinRect (g, 100, 100, 600, 600);
}
接下来,先为递归添加一个结束条件,就开始绘制所需图形,在其中间先绘制一个实心正方形,在其周围绘制八个边长为中心正方形三分之一的小正方形,以此类推,直到边长超出设定条件后结束。设定一个随机数函数,为正方形随机添加颜色,使其看起来更美观。还可以添加一个画图步骤速度的显示,呈现图形的绘制过程。
Random random=new Random ();//随机数
//设置结束条件
public void drawSheerBinRect(Graphics g, int x, int y, int w, int h){
if(w < 1){
return;
}
//画图步骤速度
try {
Thread.sleep (5);
}
catch (InterruptedException e) {
throw new RuntimeException (e);
}
// 中间实心矩形g.fillRect (x + w / 3, y + h / 3, w / 3, h / 3);
//随机添加颜色
g.setColor (new Color (random.nextInt(256),random.nextInt(256),random.nextInt(256)));
// 递归调用自己本身 绘制左上角第一个矩形
drawSheerBinRect (g, x, y, w / 3, h / 3);
// 递归调用自己本身 绘制上一层第二个矩形
drawSheerBinRect (g, x + w / 3, y, w / 3, h / 3);
// 剩下六个
drawSheerBinRect (g, x + w / 3 * 2, y, w / 3, h / 3);//右上角矩形
drawSheerBinRect (g, x, y + h / 3, w / 3, h / 3);//左边中间矩形
drawSheerBinRect (g, x + w / 3 * 2, y + h / 3, w / 3, h / 3);//右边中间矩形
drawSheerBinRect (g, x, y + h / 3 * 2, w / 3, h / 3);//左下角矩形
drawSheerBinRect (g, x + w / 3, y + h / 3 * 2, w / 3, h / 3);//下面中间矩形
drawSheerBinRect (g, x + w / 3 * 2, y + h / 3 * 2, w / 3, h / 3);//右下角矩形
}
除了添加颜色外,还可以为矩形添加图片。
Image img1 = new ImageIcon ("E:\\壁纸头像\\11.jpg").getImage ();
g.drawImage (img1, x + w / 3, y + h / 3, w / 3, h / 3, null);
完整代码如下:
package DiGui;
import javax.swing.*;
import java.awt.*;
import java.util.Random;
@SuppressWarnings("serial")
public class DrawPadJUXING extends JFrame {
// 创建一个窗体
public DrawPadJUXING(){
setTitle ("递归矩形-谢尔宾斯基地毯");
setSize (800, 800);
setDefaultCloseOperation (EXIT_ON_CLOSE);
setVisible (true);
setLocationRelativeTo (null);
}
@Override
public void paint(Graphics g){
super.paint (g);
// 绘图
drawSheerBinRect (g, 100, 100, 600, 600);
}
// Image img1 = new ImageIcon ("E:\\壁纸头像\\11.jpg").getImage ();
Random random=new Random ();
public void drawSheerBinRect(Graphics g, int x, int y, int w, int h){
if(w < 1){
return;
}
//画图步骤速度
try {
Thread.sleep (5);
}
catch (InterruptedException e) {
throw new RuntimeException (e);
}
// 外框
// g.drawRect (x, y, w, h);
// 中间实心矩形
g.setColor (new Color (random.nextInt (256), random.nextInt (256),random.nextInt(256)));//随机添加颜色
g.fillRect (x + w / 3, y + h / 3, w / 3, h / 3);
// g.drawImage (img1, x + w / 3, y + h / 3, w / 3, h / 3, null);
// 递归调用自己本身 绘制左上角第一个矩形
drawSheerBinRect (g, x, y, w / 3, h / 3);
// 递归调用自己本身 绘制上一层第二个矩形
drawSheerBinRect (g, x + w / 3, y, w / 3, h / 3);
// 剩下六个
drawSheerBinRect (g, x + w / 3 * 2, y, w / 3, h / 3);//右上角矩形
drawSheerBinRect (g, x, y + h / 3, w / 3, h / 3);//左边中间矩形
drawSheerBinRect (g, x + w / 3 * 2, y + h / 3, w / 3, h / 3);//右边中间矩形
drawSheerBinRect (g, x, y + h / 3 * 2, w / 3, h / 3);//左下角矩形
drawSheerBinRect (g, x + w / 3, y + h / 3 * 2, w / 3, h / 3);//下面中间矩形
drawSheerBinRect (g, x + w / 3 * 2, y + h / 3 * 2, w / 3, h / 3);//右下角矩形
}
public static void main(String[] args){
DrawPadJUXING dp = new DrawPadJUXING ();
}
}
结果如下: