递归算法

      在做项目过程中,常见到一些菜单,组织大部分都以递归实现,在理解递归算法上,本人总结:程序调用自身的编程技巧称为递归( recursion)。递归做为一种算法在程序设计语言中广泛应用。 一个过程或函数在其定义或说明中有直接或间接调用自身的一种方法,它通常把一个大型复杂的问题层层转化为一个与原问题相似的规模较小的问题来求解,递归策略只需少量的程序就可描述出解题过程所需要的多次重复计算,大大地减少了程序的代码量。递归的能力在于用有限的语句来定义对象的无限集合。

递归的三个条件:

  1. 边界条件
  2. 递归前进段
  3. 递归返回段

当边界条件不满足时,递归前进;当边界条件满足时,递归返回。

java递归获取某个父节点下面的所有子节点

    /** 
     * 获取某个父节点下面的所有子节点 
     * @param menuList 
     * @param pid 
     * @return 
     */  
    public static List<Menu> treeMenuList( List<Menu> menuList, int pid){  
        for(Menu mu: menuList){  
            //遍历出父id等于参数的id,add进子节点集合  
            if(Integer.valueOf(mu.getPid())==pid){  
                //递归遍历下一级  
                treeMenuList(menuList,Integer.valueOf(mu.getId()));  
                childMenu.add(mu);  
            }  
        }  
    return childMenu;  
    }  

     一、基本算法:阶乘

/**
 * 计算5的阶乘(result = 5*4*3*2*1) 
 * @author Vision
 * @date 2018年1月18日 下午3:14:29
 */
public class Factorial {
    public static void main(String[] args) {  
        System.out.println(f(5));  
    }  
      
    public static int f(int n) {  
        if (1 == n)   
            return 1;  
        else   
            return n*f(n-1);  
    }  
}
      在学习进阶过程中获取几个有趣的递归案例:汉诺塔问题

/**
 * 递归算法之爬楼梯算法
 * content:已知一个楼梯有n个台阶,每次可以选择迈上一个或者两个台阶,求走完一共有多少种不同的走法。
 * @author Vision
 * @date 2018年1月18日 下午2:47:53
 */
public class ClimbStairs {
    public int climbStairs(int n) {
        int i=1;
         if(n<=0)
            return 0;
         if(n==1){
             return i;
         }
         if(n==2){
             i++;
             return i;
         }
         else
             return climbStairs(n-1)+climbStairs(n-2);
   }
     public static void main(String []args){
         ClimbStairs cs=new ClimbStairs();
         int a =cs.climbStairs(4);
         System.out.println(a);
     }
/**
 * 递归函数之汉诺塔问题
 * content:一次只能移动一个盘子;不能把大盘子放在小盘子上;除去盘子在两个柱子之间移动的瞬间,盘子必须都在柱子上。(在这三点要求下把盘子从起始柱子A全部移动到目标柱子C上)
 * 基础情形:n==1的时候终止递归,进行回溯。
 * @author Vision
 * @date 2018年1月18日 下午2:51:41
 */
public class HanNuoTower {
	   public void tower(int n,char s,char m,char e)//n个塔从s经过m最终全部移动到e
	    {
	        if(n==1)
	            move(s,e);
	        else
	        {
	            tower(n-1,s,e,m);
	            move(s,e);
	            tower(n-1,m,s,e);
	        }
	    }
	    public void move(char s,char e){
	        System.out.println("move "+s+" to "+e);
	    }
	    public static void main(String []args){
	        HanNuoTower hnt =new HanNuoTower();
	        hnt.tower(3,'A','B','C');
	    }
}
/**
 * 递归函数之迷宫走法:
 * content:二维数组构成一个迷宫,1表示通路,0表示不通,找到一条路径从起始点(traverse函数的参数)到终点(右下角点)。
 * @author Vision
 * @date 2018年1月18日 下午3:01:43
 */
public class Maze {
	private final int	TRIED	= 3;
	private final int	PATH	= 7;

	private int[][]		grid	= { 
			{ 1, 1, 1, 0, 0, 1, 0, 1, 0, 0 }, 
			{ 0, 0, 1, 1, 1, 0, 0, 0, 0, 0 },
			{ 1, 0, 1, 0, 0, 0, 1, 1, 1, 1 }, 
			{ 1, 1, 1, 1, 1, 0, 0, 0, 1, 1 }, 
			{ 0, 0, 0, 0, 1, 1, 1, 0, 0, 0 },
			{ 1, 0, 1, 0, 1, 0, 0, 1, 0, 0 }, 
			{ 1, 0, 0, 1, 1, 1, 1, 1, 1, 1 } 
	};

	public boolean traverse(int row, int column) {
		boolean done = false;
		if (valid(row, column)) {
			grid[row][column] = TRIED;
			if (row == grid.length - 1 && column == grid[0].length - 1)
				done = true;
			else {
				done = traverse(row + 1, column);// down
				if (!done)
					done = traverse(row, column + 1);// right
				if (!done)
					done = traverse(row - 1, column);// up
				if (!done)
					done = traverse(row, column - 1);// left
			}
			if (done)
				grid[row][column] = PATH;
		}
		return done;
	}

	private boolean valid(int row, int column) {
		boolean result = false;
		if (row >= 0 && row < grid.length && column >= 0 && column < grid[row].length)
			if (grid[row][column] == 1)
				result = true;
		return result;
	}

	public String toString() {
		String result = "\n";
		for (int row = 0; row < grid.length; row++) {
			for (int column = 0; column < grid[row].length; column++) {
				result += grid[row][column] + " ";
			}
			result += "\n";
		}
		return result;
	}

	public static void main(String[] args) {
		Maze maze = new Maze();
		System.out.println(maze);
		if (maze.traverse(0, 0))
			System.out.println("The maze was successfully travelled!");
		else
			System.out.println("There is no possible path.");
		System.out.println(maze);
	}
}
、
1 1 1 0 0 1 0 1 0 0 
0 0 1 1 1 0 0 0 0 0 
1 0 1 0 0 0 1 1 1 1 
1 1 1 1 1 0 0 0 1 1 
0 0 0 0 1 1 1 0 0 0 
1 0 1 0 1 0 0 1 0 0 
1 0 0 1 1 1 1 1 1 1 

The maze was successfully travelled!

7 7 7 0 0 1 0 1 0 0 
0 0 7 1 1 0 0 0 0 0 
1 0 7 0 0 0 1 1 1 1 
1 1 7 7 7 0 0 0 1 1 
0 0 0 0 7 1 1 0 0 0 
1 0 1 0 7 0 0 1 0 0 
1 0 0 1 7 7 7 7 7 7
      有些初学者可能认为递归即是自己调用自己,那岂不是死循环了。对,如果递归写的不合理,那就是死循环了。但是如果写的合理,加上“边界条件”,程序执行到底的时候,会逐层返回。







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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值