Java中的递归分形

递归的概念:是指在方法的定义中使用方法自身。也就是说,递归算法是一种直接或者间接调用自身方法的算法。简言之:在定义自身的同时又出现自身的直接或间接调用

注意:递归必须要有一个退出的条件!!!

        下面写一个简单的程序实现一下递归,即:程序自己调用自己。

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 ();
	}
}

结果如下:

/** * 根据等级查询类目树 * * @param level * @return */ @Override public List queryCategoryTree(Integer level) { //查询当前级别下类目 List list = categoryDAO.list(level); //组装好的类目树,返回前端 List categoryTree = new ArrayList(); //所有类目 List allDTOList = new ArrayList(); if (CollectionUtils.isEmpty(list)) { return categoryTree; } for (CategoryDO categoryDO : list) { allDTOList.add(new CategoryTreeDTO().convertDOToDTO(categoryDO)); } //当前等级类目 categoryTree = allDTOList.stream().filter(dto -> level.equals(dto.getLevel())).collect(Collectors.toList()); for (CategoryTreeDTO categoryTreeDTO : categoryTree) { //组装类目为树结构 assembleTree(categoryTreeDTO, allDTOList,Constants.CATEGORY_MAX_LEVEL - level); } return categoryTree; } /** * 组装树 * * @param categoryTreeDTO * @param allList * @param remainRecursionCount 剩余递归次数 * @return */ public CategoryTreeDTO assembleTree(CategoryTreeDTO categoryTreeDTO, List allList, int remainRecursionCount) { remainRecursionCount--; //最大递归次数不超过Constants.CATEGORY_MAX_LEVEL-level次,防止坏数据死循环 if(remainRecursionCount < 0){ return categoryTreeDTO; } String categoryCode = categoryTreeDTO.getCategoryCode(); Integer level = categoryTreeDTO.getLevel(); //到达最后等级树返回 if (Constants.CATEGORY_MAX_LEVEL == level) { return categoryTreeDTO; } //子类目 List child = allList.stream().filter(a -> categoryCode.equals(a.getParentCode())).collect(Collectors.toList()); if (null == child) { return categoryTreeDTO; } categoryTreeDTO.setChildren(child); //组装子类目 for (CategoryTreeDTO dto : child) { assembleTree(dto, allList,remainRecursionCount); } return categoryTreeDTO; }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值