Java实现简单的递归操作[通俗易懂]

Java实现简单的递归操作[通俗易懂]在数据结构算法设计中,或者一个方法的具体实现的时候,有一种方法叫做“递归”,这种方法在思想上并不是特别难,但是实现起来还是有一些需要注意的。虽然对于很多递归算法都可以由相应的循环迭代来代替,但是对于一些比较抽象复杂的算法不用递归很难理解与实现。递归分为直接递归和间接递归,就简单分享一下两个小的直接递归。对于递归的概念,其实你可以简单的理解为自己定义自己,记得小时候看过一部电视剧《狼毒花》,…

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE使用 1年只要46元 售后保障 童叟无欺

在数据结构算法设计中,或者一个方法的具体实现的时候,有一种方法叫做“递归”,这种方法在思想上并不是特别难,但是实现起来还是有一些需要注意的。虽然对于很多递归算法都可以由相应的循环迭代来代替,但是对于一些比较抽象复杂的算法不用递归很难理解与实现。
递归分为直接递归和间接递归,就简单分享一下两个小的直接递归。
对于递归的概念,其实你可以简单的理解为自己定义自己,记得小时候看过一部电视剧《狼毒花》,里面主角叫做“常发”,但是个文盲,老师问他叫什么,他说“常发”。“哪个常?”“常发的常啊!”“哪个发?”“常发的发啊!”结果第二节课老师就让一群小朋友一起喊“常发的常,常发的发,傻瓜的傻,傻瓜的瓜”。言归正传,显然在多数情况下递归是解释一个想法或者定义的一种合理方法。在思想上递归类似于数学中曾经学过的数学归纳法。
递归的实现:
递归的实现要注意有两点:一个递归的选项和一个非递归的选项,后者成为基础情形(base case)。基础情形是递归的终结情形,没有基础情形或者处理不好都会导致无穷递归,这是我们不想要的结果。递归实现起来最关键的是处理好基础情形。 结合具体事例在说一下递归回溯的过程。
下边来写两个小程序:
1、爬楼梯算法:已知一个楼梯有n个台阶,每次可以选择迈上一个或者两个台阶,求走完一共有多少种不同的走法。
方法如下:
这里写图片描述
递归函数有返回值的比没有返回值的麻烦一点,因为一个函数只有一个返回值,但是递归还要求有基础情形的存在,所以还必须有if判断来终止递归。所以在每一个if或者else后边都有一个return,这样保证函数在任何一种情况下都有且仅有一个返回值。
分析一下这个算法:
A:如果有0个台阶,那么有0种走法,这个不用多说;
B:如果有1个台阶,那么有1种走法;
C:如果有2个台阶,那么有2种走法(一次走1个,走两次;一次走两个);
以上的B和C就是基础情形。
D:接下来就是递归了,如果台阶数目多于2个,那么首先第一步就有两种选择:第一次走1个,或者第一次走两个。这样除了第一次后边的走法就有了两种情形:climbStairs(n-1)和climbStairs(n-2)。这样一直递归下去,直到出现到了基础情形(即n=1或n=2的情形),递归到这个地方(基础情形),然后开始回溯 ,这就是所说的和递归密切相关的“回溯”了。回溯,顾名思义就是从结果倒着回去,找到整个过程,进而分析这个路径或者说是实现的过程。

需要注意的是,这个算法实现思路上简单,但是复杂度并没有降低,还牵扯回溯保存堆栈问题(其实递归的设计尽量避免这种嵌套两个的递归方式(climb(n)中包含climb(n-1)和climb(n-2)),这种操作会使得堆栈开辟空间随着n的增大以指数型增长,最终程序很容易崩溃),而且在台阶数目多到一定数量的时候会越界(走法次数会超出int的范围),所以递归程序很大程度上就是思想实现设计上简单理解一些。
下边是源代码:

package leetcode;

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

}

然后还有几个比较典型的递归问题:比如说迷宫问题,或者最经典的汉诺塔问题,下边都给出源码,大家一块儿学习一下。

汉诺塔问题:一次只能移动一个盘子;不能把大盘子放在小盘子上;除去盘子在两个柱子之间移动的瞬间,盘子必须都在柱子上。(在这三点要求下把盘子从起始柱子A全部移动到目标柱子C上)
这里写图片描述
代码如下:
基础情形:n==1的时候终止递归,进行回溯。

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(4,'A','B','C');
	}

}

迷宫走法:二维数组构成一个迷宫,1表示通路,0表示不通,找到一条路径从起始点(traverse函数的参数)到终点(右下角点)。

基础情形:row=grid.length-1&&column=grid[0].length-1时done=true;


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

}

还有一个九连环的操作,有兴趣的话可以一起看看。Java递归解决九连环问题
如有不得当之处,还望诸位大神指教!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/192035.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)
blank

相关推荐

  • Java代码是怎么运行的「建议收藏」

    Java代码是怎么运行的「建议收藏」Java代码有很多运行方式。在开发工具中运行双击jar文件运行在命令行中运行在网页中运行当然,上述运行方式都离不开JRE,&nbsp;也就是Java运行时环境。JRE仅包含Java程序的必须组件,包括Java虚拟机以及Java核心类库…

  • bat 剪切文件_bat延时命令

    bat 剪切文件_bat延时命令扩展名是bat(在nt/2000/xp/2003下也可以是cmd)的文件就是批处理文件。首先批处理文件是一个文本文件,这个文件的每一行都是一条DOS命令(大部分时候就好象我们在DOS提示符下执行的命令行一样),你可以使用DOS下的Edit或者Windows的记事本(notepad)等任何文本文件编辑工具创建和修改批处理文件。其次,批处理文件是一种简单的程序,可以通过条件语句(if)和流程控制语句(…

  • Fiddler4入门——手机抓包

    Fiddler4入门——手机抓包fiddler手机抓包原理及详细的相关配置

  • html表格菜鸟教程_exls表格

    html表格菜鸟教程_exls表格HTML基础之表格文章目录HTML基础之表格1.表格的定义2.表格的标签3.单元格边框(border)4.合并单元格4.1合并行单元格(colspan)4.2合并列单元格(rowspan)5.表格格式设置5.1单元格的对齐(align)(居中,左对齐,右对齐)5.2.背景色&图片(bgcolor&background)5.2.1单元格背景色&图片5.2.2表格背景色&图片5.3单元格的边距(cellpadding)5.4单元格间的距离(cel

  • 安装linux的基本步骤_linux安装oracle

    安装linux的基本步骤_linux安装oracle文章目录一、下载Python包二、安装依赖环境三、安装Python3四、建立Python3和pip3的软链五、检查是否安装成功点我获取更多教程、面试经验、Python分享(PS:个人在用的人工智能学习网站推荐给需要的小伙伴:captainai)一、下载Python包网上教程大多是通过官方地址进行下载Python的,但由于国内网络环境问题,会导致下载很慢,所以这里建议通过国内镜像进行下载例如:淘宝镜像http://npm.taobao.org/mirrors/python/大部分版本和

  • SecureCRT的下载、安装( 过程非常详细!!值得查看)

    SecureCRT的下载、安装( 过程非常详细!!值得查看)SecureCRT的下载、安装和破解(过程非常详细!!值得查看)简单介绍下SecureCRT一、SecureCRT的下载二、SecureCRT的安装简单介绍下SecureCRTSecureCRT是一款支持SSH(SSH1和SSH2)的终端仿真程序,简单地说是Windows下登录UNIX或Linux服务器主机的软件。SecureCRT支持SSH,同时支持Telnet和rlogin协议。Secu…

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号