在做项目过程中,常见到一些菜单,组织大部分都以递归实现,在理解递归算法上,本人总结:程序调用自身的编程技巧称为递归( recursion)。递归做为一种算法在程序设计语言中广泛应用。 一个过程或函数在其定义或说明中有直接或间接调用自身的一种方法,它通常把一个大型复杂的问题层层转化为一个与原问题相似的规模较小的问题来求解,递归策略只需少量的程序就可描述出解题过程所需要的多次重复计算,大大地减少了程序的代码量。递归的能力在于用有限的语句来定义对象的无限集合。
递归的三个条件:
- 边界条件
- 递归前进段
- 递归返回段
当边界条件不满足时,递归前进;当边界条件满足时,递归返回。
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
有些初学者可能认为递归即是自己调用自己,那岂不是死循环了。对,如果递归写的不合理,那就是死循环了。但是如果写的合理,加上“边界条件”,程序执行到底的时候,会逐层返回。