java递归的经典例子
java 递归树结构获取根节点
java 递归树结构获取根节点在Java中,要获取树结构的根节点,可以使用递归的方式来实现。
首先,我们需要定义树节点的数据结构,然后编写递归函数来遍历树并找到根节点。
首先,我们创建一个简单的树节点类,该类包含节点值和子节点列表:java.public class TreeNode {。
int val;List<TreeNode> children;public TreeNode(int val) {。
this.val = val;children = new ArrayList<>();}。
}。
接下来,我们编写一个递归函数来查找根节点。
递归函数将遍历树的每个节点,并检查每个节点的父节点是否为空,如果父节点为空,则当前节点就是根节点。
如果父节点不为空,则继续向上递归查找根节点。
java.public TreeNode findRoot(TreeNode node) {。
if (node == null) {。
return null;}。
if (node.parent == null) {。
return node;}。
return findRoot(node.parent);}。
在这个递归函数中,我们传入一个节点作为参数,然后检查该节点的父节点是否为空,如果为空则返回该节点,否则继续递归查找父节点,直到找到根节点为止。
最后,我们可以调用这个递归函数来获取树结构的根节点:java.TreeNode root = findRoot(someNode);这样,我们就可以使用递归的方式来获取树结构的根节点。
这种方法可以适用于任何复杂度的树结构,并且能够准确地找到根节点。
java-递归练习
java-递归练习1、从键盘接收⼀个⽂件夹路径,统计该⽂件夹⼤⼩1public class Test1 {23/**4 * @param args5 * 需求:1,从键盘接收⼀个⽂件夹路径,统计该⽂件夹⼤⼩6 *7 * 从键盘接收⼀个⽂件夹路径8 * 1,创建键盘录⼊对象9 * 2,定义⼀个⽆限循环10 * 3,将键盘录⼊的结果存储并封装成File对象11 * 4,对File对象判断12 * 5,将⽂件夹路径对象返回13 *14 * 统计该⽂件夹⼤⼩15 * 1,定义⼀个求和变量16 * 2,获取该⽂件夹下所有的⽂件和⽂件夹listFiles();17 * 3,遍历数组18 * 4,判断是⽂件就计算⼤⼩并累加19 * 5,判断是⽂件夹,递归调⽤20*/21public static void main(String[] args) {22//File dir = new File("F:\\day06");23//System.out.println(dir.length()); //直接获取⽂件夹的结果是024 File dir = getDir();25 System.out.println(getFileLength(dir));2627 }2829/*30 * 从键盘接收⼀个⽂件夹路径31 * 1,返回值类型File32 * 2,参数列表⽆33*/34public static File getDir() {35//1,创建键盘录⼊对象36 Scanner sc = new Scanner(System.in);37 System.out.println("请输⼊⼀个⽂件夹路径:");38//2,定义⼀个⽆限循环39while(true) {40//3,将键盘录⼊的结果存储并封装成File对象41 String line = sc.nextLine();42 File dir = new File(line);43//4,对File对象判断44if(!dir.exists()) {45 System.out.println("您录⼊的⽂件夹路径不存在,请输⼊⼀个⽂件夹路径:");46 }else if(dir.isFile()) {47 System.out.println("您录⼊的是⽂件路径,请输⼊⼀个⽂件夹路径:");48 }else {49//5,将⽂件夹路径对象返回50return dir;51 }52 }5354 }5556/*57 * 统计该⽂件夹⼤⼩58 * 1,返回值类型long59 * 2,参数列表File dir60*/61public static long getFileLength(File dir) { //dir = F:\day06\day0762//1,定义⼀个求和变量63long len = 0;64//2,获取该⽂件夹下所有的⽂件和⽂件夹listFiles();65 File[] subFiles = dir.listFiles(); //day07 Demo1_Student.class Demo1_Student.java66//3,遍历数组67for (File subFile : subFiles) {68//4,判断是⽂件就计算⼤⼩并累加69if(subFile.isFile()) {70 len = len + subFile.length();71//5,判断是⽂件夹,递归调⽤72 }else {73 len = len + getFileLength(subFile);74 }75 }76return len;77 }78 }2、从键盘接收⼀个⽂件夹路径,删除该⽂件夹1public class Test2 {23/**4 * 需求:2,从键盘接收⼀个⽂件夹路径,删除该⽂件夹5 *6 * 删除该⽂件夹7 * 分析:8 * 1,获取该⽂件夹下的所有的⽂件和⽂件夹9 * 2,遍历数组10 * 3,判断是⽂件直接删除11 * 4,如果是⽂件夹,递归调⽤12 * 5,循环结束后,把空⽂件夹删掉13*/14public static void main(String[] args) {15 File dir = Test1.getDir(); //获取⽂件夹路径16 deleteFile(dir);17 }1819/*20 * 删除该⽂件夹21 * 1,返回值类型 void22 * 2,参数列表File dir23*/24public static void deleteFile(File dir) {25//1,获取该⽂件夹下的所有的⽂件和⽂件夹26 File[] subFiles = dir.listFiles();27//2,遍历数组28for (File subFile : subFiles) {29//3,判断是⽂件直接删除30if(subFile.isFile()) {31 subFile.delete();32//4,如果是⽂件夹,递归调⽤33 }else {34 deleteFile(subFile);35 }36 }37//5,循环结束后,把空⽂件夹删掉38 dir.delete();39 }40 }3、从键盘接收两个⽂件夹路径,把其中⼀个⽂件夹中(包含内容)拷贝到另⼀个⽂件夹中 1public class Test3 {23/**4 * 需求:3,从键盘接收两个⽂件夹路径,把其中⼀个⽂件夹中(包含内容)拷贝到另⼀个⽂件夹中5 *6 * 把其中⼀个⽂件夹中(包含内容)拷贝到另⼀个⽂件夹中7 * 分析:8 * 1,在⽬标⽂件夹中创建原⽂件夹9 * 2,获取原⽂件夹中所有的⽂件和⽂件夹,存储在File数组中10 * 3,遍历数组11 * 4,如果是⽂件就⽤io流读写12 * 5,如果是⽂件夹就递归调⽤13 * @throws IOException14*/15public static void main(String[] args) throws IOException {16 File src = Test1.getDir();17 File dest = Test1.getDir();18if(src.equals(dest)) {19 System.out.println("⽬标⽂件夹是源⽂件夹的⼦⽂件夹");20 }else {21 copy(src,dest);22 }23 }24/*25 * 把其中⼀个⽂件夹中(包含内容)拷贝到另⼀个⽂件夹中26 * 1,返回值类型void27 * 2,参数列表File src,File dest28*/29public static void copy(File src, File dest) throws IOException {30//1,在⽬标⽂件夹中创建原⽂件夹31 File newDir = new File(dest, src.getName());32 newDir.mkdir();33//2,获取原⽂件夹中所有的⽂件和⽂件夹,存储在File数组中34 File[] subFiles = src.listFiles();35//3,遍历数组36for (File subFile : subFiles) {37//4,如果是⽂件就⽤io流读写38if(subFile.isFile()) {39 BufferedInputStream bis = new BufferedInputStream(new FileInputStream(subFile));40 BufferedOutputStream bos =41new BufferedOutputStream(new FileOutputStream(new File(newDir,subFile.getName()))); 4243int b;44while((b = bis.read()) != -1) {45 bos.write(b);46 }4748 bis.close();49 bos.close();50//5,如果是⽂件夹就递归调⽤51 }else {52 copy(subFile,newDir);53 }54 }55 }56 }4、从键盘接收⼀个⽂件夹路径,把⽂件夹中的所有⽂件以及⽂件夹的名字按层级打印1public class Test4 {23/**4 * 需求:4,从键盘接收⼀个⽂件夹路径,把⽂件夹中的所有⽂件以及⽂件夹的名字按层级打印, 例如:5 * 把⽂件夹中的所有⽂件以及⽂件夹的名字按层级打印6 * 分析:7 * 1,获取所有⽂件和⽂件夹,返回的File数组8 * 2,遍历数组9 * 3,⽆论是⽂件还是⽂件夹,都需要直接打印10 * 4,如果是⽂件夹,递归调⽤11 * day0712 * day0813 * xxx.jpg14 * yyy.txt15 * Demo1_Consturctor.class16 * Demo1_Consturctor.java17 * Demo1_Student.class18 * Demo1_Student.java19*/20public static void main(String[] args) {21 File dir = Test1.getDir(); //获取⽂件夹路径22 printLev(dir,0);23 }2425public static void printLev(File dir,int lev) {26//1,把⽂件夹中的所有⽂件以及⽂件夹的名字按层级打印27 File[] subFiles = dir.listFiles();28//2,遍历数组29for (File subFile : subFiles) {30for(int i = 0; i <= lev; i++) {31 System.out.print("\t");32 }33//3,⽆论是⽂件还是⽂件夹,都需要直接打印34 System.out.println(subFile);35//4,如果是⽂件夹,递归调⽤36if(subFile.isDirectory()) {37//printLev(subFile,lev + 1);38 printLev(subFile,++lev);39 }40 }41 }4243 }5、斐波那契数列1public class Test5 {23/**4 * * 不死神兔5 * 故事得从西元1202年说起,话说有⼀位意⼤利青年,名叫斐波那契。
java递归算法经典题目
java递归算法经典题目递归是一种常见的算法思想,它通过将问题分解为更小的子问题来解决问题。
在Java中,递归算法可以用于解决许多经典问题,如斐波那契数列、汉诺塔、阶乘等。
下面我们将介绍一些Java递归算法经典题目,帮助您更好地理解和掌握递归算法。
1.斐波那契数列斐波那契数列是一个经典的递归问题,它是指从第0项开始,每一项都是前两项的和。
在Java中,可以使用递归方法来求解斐波那契数列。
以下是一个简单的递归算法实现:```javapublicstaticintfibonacci(intn){if(n<=1){returnn;}else{returnfibonacci(n-1)+fibonacci(n-2);}}```这个算法会一直递归调用直到达到斐波那契数列的末项为止。
需要注意的是,递归算法的时间复杂度较高,当n值较大时可能会导致栈溢出等问题。
2.汉诺塔问题汉诺塔问题是一个经典的递归问题,它描述了一个操作:将一堆盘子从一个柱子移动到另一个柱子,要求遵循以下规则:每次只能移动一个盘子,并且大盘子不能放在小盘子上面。
在Java中,可以使用递归方法来解决汉诺塔问题。
以下是一个简单的递归算法实现:```javapublicstaticvoidhanoi(intn,Stringfrom,Stringto,Stringvia) {if(n==1){System.out.println("Movedisk"+n+"from"+from+"to"+to);}else{hanoi(n-1,from,via,to);System.out.println("Movedisk1from"+from+"to"+to);hanoi(n-1,via,to,from);}}```这个算法会一直递归调用,直到完成所有盘子的移动。
JAVA递归生成树形菜单
JAVA递归⽣成树形菜单 递归⽣成⼀个如图的菜单,编写两个类数据模型Menu、和创建树形的MenuTree。
通过以下过程实现: 1.⾸先从菜单数据中获取所有根节点。
2.为根节点建⽴次级⼦树并拼接上。
3.递归为⼦节点建⽴次级⼦树并接上,直⾄为末端节点拼接上空的“树”。
⾸先,编写数据模型Menu。
每条菜单有⾃⼰的id、⽗节点parentId、菜单名称text、菜单还拥有次级菜单children。
1import java.util.List;23public class Menu {4private String id;5private String parentId;6private String text;7private String url;8private String yxbz;9private List<Menu> children;10public Menu(String id,String parentId,String text,String url,String yxbz) {11this.id=id;12this.parentId=parentId;13this.text=text;14this.url=url;15this.yxbz=yxbz;16 }17/*省略get\set*/18 } 创建树形结构的类MenuTree。
⽅法getRootNode获取所有根节点,⽅法builTree将根节点汇总创建树形结构,buildChilTree为节点建⽴次级树并拼接上当前树,递归调⽤buildChilTree不断为当前树开枝散叶直⾄找不到新的⼦树。
完成递归,获取树形结构。
1import java.util.ArrayList;2import java.util.List;34public class MenuTree {5private List<Menu> menuList = new ArrayList<Menu>();6public MenuTree(List<Menu> menuList) {7this.menuList=menuList;8 }910//建⽴树形结构11public List<Menu> builTree(){12 List<Menu> treeMenus =new ArrayList<Menu>();13for(Menu menuNode : getRootNode()) {14 menuNode=buildChilTree(menuNode);15 treeMenus.add(menuNode);16 }17return treeMenus;18 }1920//递归,建⽴⼦树形结构21private Menu buildChilTree(Menu pNode){22 List<Menu> chilMenus =new ArrayList<Menu>();23for(Menu menuNode : menuList) {24if(menuNode.getParentId().equals(pNode.getId())) {25 chilMenus.add(buildChilTree(menuNode));26 }27 }28 pNode.setChildren(chilMenus);29return pNode;30 }3132//获取根节点33private List<Menu> getRootNode() {34 List<Menu> rootMenuLists =new ArrayList<Menu>();35for(Menu menuNode : menuList) {36if(menuNode.getParentId().equals("0")) {37 rootMenuLists.add(menuNode);38 }39 }40return rootMenuLists;41 }42 } 最后,插⼊⼀些数据试试效果。
java递归处理父节点选中状态
一、简介Java是一种面向对象的程序设计语言,递归是一种解决问题的常用方法,可以通过递归的方式来处理父节点的选中状态。
本文将介绍如何使用Java递归来处理父节点的选中状态,以及一些注意事项和实际应用中的示例。
二、递归处理父节点选中状态的原理1. 父节点选中状态与子节点的关系在树形结构中,父节点的选中状态通常与其子节点的选中状态有关。
当子节点全部选中时,父节点才会被选中;当子节点有部分未选中或全部未选中时,父节点则不应该被选中。
2. 递归调用的实现为了处理父节点的选中状态,我们可以使用递归的方式来遍历树形结构。
当子节点的选中状态发生变化时,可以递归地向上更新父节点的选中状态,直到根节点为止。
三、 Java中的递归处理父节点选中状态的实现1. 定义树形结构的数据模型我们需要定义树形结构的数据模型,通常可以使用树节点的类来表示。
每个树节点包含一个值和一个子节点列表,以及一个选中状态的属性。
2. 递归更新父节点的选中状态当子节点的选中状态发生变化时,可以递归地向上更新父节点的选中状态。
具体实现时,可以使用递归函数来完成这一过程。
四、注意事项1. 避免递归调用的深度过深在实际应用中,递归调用的深度应当受到限制,以避免栈溢出的风险。
可以考虑使用迭代代替递归,或者采用尾递归的方式优化递归调用。
2. 处理循环引用的情况如果树形结构中存在循环引用的情况,递归调用可能会导致无限循环。
在实际应用中,需要考虑如何处理这种情况,以避免程序陷入死循环。
五、实际应用中的示例1. 文件夹结构的表示在文件管理系统中,可以使用树形结构表示文件夹的层次关系。
当用户勾选某个文件夹时,可能需要递归更新其父文件夹的选中状态。
2. 商品类别的多级选择在电商全球信息站中,商品类别通常是多级的,用户可以选择某个类别来浏览商品。
当用户选择某个类别时,可能需要递归更新其所有父类别的选中状态。
六、总结通过本文的介绍,我们了解了如何使用Java递归来处理父节点的选中状态。
递归经典题目
递归经典题目
递归是一种常用的算法技术,它可以用来解决许多经典问题。
以下是一些经典的递归问题:
1. 斐波那契数列:这是一个经典的递归问题,其中每个数字是前两个数字的和。
例如,斐波那契数列的前几个数字是 0、1、1、2、3、5、8、13、21 等。
2. 阶乘函数:这是一个计算一个数的阶乘的递归函数。
例如,5 的阶乘是 5 4 3 2 1 = 120。
3. 汉诺塔问题:这是一个经典的递归问题,其中有一些盘子需要从一根柱子移动到另一根柱子,每次只能移动一个盘子,并且不能将一个较大的盘子放在较小的盘子上面。
4. 二分搜索:这是一个在排序数组中查找特定元素的递归算法。
它首先将数组分成两半,然后根据目标值与中间元素的比较结果,选择另一半继续搜索。
5. 回溯算法:这是一种通过递归搜索所有可能解的算法,通常用于解决约束满足问题。
例如,排列组合问题、八皇后问题等。
6. 分治算法:这是一种将问题分解为更小的子问题,然后递归地解决这些子问题的算法。
例如,归并排序和快速排序等。
7. 动态规划:这是一种使用递归和备忘录(或称为记忆化)的方法,用于解决具有重叠子问题和最优子结构的问题。
例如,背包问题和最短路径问题等。
这些经典的递归问题涵盖了不同的应用领域和算法类型,可以通过学习和解决这些问题来提高自己的编程和算法技能。
Java实现递归将嵌套Map里的字段名由驼峰转为下划线
Java实现递归将嵌套Map⾥的字段名由驼峰转为下划线摘要:使⽤Java语⾔递归地将Map⾥的字段名由驼峰转下划线。
通过此例可以学习如何递归地解析任意嵌套的List-Map容器结构。
难度:初级概述###在进⾏多语⾔混合编程时,由于编程规范的不同,有时会需要进⾏字段名的驼峰-下划线转换。
⽐如 php 语⾔中,变量偏向于使⽤下划线,⽽Java 语⾔中,变量偏向于驼峰式。
当 PHP 调⽤ java 接⼝时,就需要将 java 返回数据结构中的驼峰式的字段名称改为下划线。
使⽤ jackson 解析 json 数据时,如果不指定解析的类,常常会将 json 数据转化为 LinkedHashMap 。
因此,需要将 LinkedHashMap ⾥的字段名由驼峰转为下划线。
这⾥的难点是, Map 结构可能是⾮常复杂的嵌套结构,⼀个 Map 的某个 key 对应的 value 可能是原⼦的,⽐如字符串,整数等,可能是嵌套的 Map, 也可能是含有多个 Map 的 List , ⽽ map , list 内部⼜可能嵌套任意的 map 或 list . 因此,要使⽤递归的算法来将 value ⾥的 key 递归地转化为下划线。
算法设计###⾸先,要编写⼀个基本函数 camelToUnderline,将⼀个字符串的值从驼峰转下划线。
这个函数不难,逐字符处理,遇到⼤写字母就转成 _ + ⼩写字母;或者使⽤正则表达式替换亦可;其次,需要使⽤基本函数 camelToUnderline 对可能多层嵌套的 Map 结构进⾏转化。
假设有⼀个函数 transferKeysFromCamelToUnderline(amap) ,可以将 amap ⾥的所有 key 从驼峰转化为下划线,包括 amap ⾥嵌套的任意 map。
返回结果是 resultMap ;(1) ⾸先考虑最简单的情况:没有任何嵌套的情况,原⼦类型的 key 对应原⼦类型的 value ; resultMap.put(newkey, value) 即可 , newkey = camelToUnderline(key);(2) 其次考虑 Map 含有嵌套 subMap 的情况:假设 <key, value> 中,value 是⼀个 subMap, 那么,调⽤ camelToUnderline(key) 可以得到新的 newkey ,调⽤ transferKeysFromCamelToUnderline(subMap) 就得到转换了的 newValue , 得到 <newkey, newValue>; resultMap.put(newkey, newValue)(3) 其次考虑 Map 含有 List 的情况: List ⾥通常含有多个 subMap ,只要遍历⾥⾯的 subMap 进⾏转换并添加到新的 List, ⾥⾯含有所有转换了的newValue = map(transferKeysFromCamelToUnderline, List[subMap]); resultMap.put(newkey, newValue) .递归技巧####当使⽤递归⽅式思考的时候,有三个技巧值得注意:(1) ⾸先,⼀定从最简单的情况开始思考。
汉诺塔-经典递归算法(java描述)
汉诺塔—经典递归算法(java描述)汉诺塔:(又称河内塔)问题是源于印度一个古老传说的益智玩具。
大梵天创造世界的时候做了三根金刚石柱子,在一根柱子上从下往上按照大小顺序摞着64片黄金圆盘。
大梵天命令婆罗门把圆盘从下面开始按大小顺序重新摆放在另一根柱子上。
并且规定,在小圆盘上不能放大圆盘,在三根柱子之间一次只能移动一个圆盘。
整个算法要解决的是:将第一根柱子上的64个圆盘,借助第二根柱子,移到第三根柱子上,并确保小盘在大盘之上。
解决思路:(三根柱子设为X,Y,Z)1、先将前63个圆盘(看成一个圆盘)从X柱移到Y柱,确保大盘在小盘之下;(问题一)2、将第64个圆盘从X柱移到Z柱;3、再将前63个圆盘(看成一个圆盘)从Y柱移到Z柱,确保大盘在小盘之下。
(问题二)现在要解决:问题一:将X柱上的前63个圆盘,借助Z柱,移到Y柱上;问题二:将Y柱上的前63个圆盘,借助X柱,移到Z柱上;问题一的圆盘移动步骤:1、先将前62个圆盘,从X柱移到Z柱上;2、将第63个圆盘,从X柱移到Y柱上;3、在将前62个圆盘,从Z柱上移动到Y柱上。
问题二的圆盘移动步骤:1、先将前62个圆盘,从Y柱移到X柱;2、将第63个圆盘,从Y柱移到Z柱;3、再将前62个圆盘,从X柱移到Z柱。
从以上推导出推递归方法;问题一:1、先将前n-1个圆盘,从X柱移到Z柱;2、将第n个圆盘,从X柱移到Y柱;3、再将前n-1个圆盘,从Z柱移到Y柱。
问题二:1、先将前n-1个圆盘,从Y柱移到X柱;2、将第n个圆盘,从Y柱移到Z柱;3、再将前n-1个圆盘,从X柱移到Z柱。
主要代码思路(不能执行的):hanoi(n-1,’X’,’Z’,’Y’);//将X柱上的前n-1个圆盘,借助Z柱,移到Y柱上(问题一)move(n,’X’,’Z’);//将第n个圆盘,从X柱移到Z柱hanoi(n-1,’Y’,’X’,’Z’);//将Y柱上的前n-1个圆盘,借助X柱,移到Z柱上(问题二)递归的持续机制:当n>1时退出机制:当n=1时具体实现代码(java):import java.io.*;public class HanoiTowerDemo{public static void main(String[] args){try{BufferedReader br=new BufferedReader(new InputStreamReader(System.in));System.out.print("请输入汉诺塔总层数:");int n=Integer.parseInt(br.readLine());System.out.println("开始游戏,移动步骤是:");hanoi(n,'X','Y','Z');//将X柱上的n个圆盘,借助Y柱,移到Z柱}catch (Exception ex){}}/*功能:将X柱上的n个圆盘,借助Y柱,移到Z柱*/public static void hanoi(int n,char x,char y,char z){if(n==1)move(x,z); //将X柱上的圆盘移到Z柱上elseif(n>1){hanoi(n-1,x,z,y);//将X柱上的前n-1个圆盘,借助Z盘移到Y盘move(x,z);//将X柱上的圆盘移到Z柱上hanoi(n-1,y,x,z);//将Y柱上的前n-1个圆盘,借助X柱移到Z盘}}/*功能:将X柱上的圆盘移到Z柱上*/private static void move(char x,char z){System.out.println(x+" -> "+z);}}。
return;在java中的用法
在Java中,return是一个关键字,用于指示方法返回值或中断方法的执行。
它被广泛用于方法的定义和控制流程的处理。
本文将深入探讨return在Java中的用法,并分析其在不同情境下的实际应用。
1. return的基本用法在Java中,return的基本用法是指示方法返回值。
当方法声明了返回类型时,使用return可以将指定类型的值返回给方法的调用者。
一个求和的方法可以如下定义:```javapublic int sum(int a, int b) {return a + b;}```在上面的例子中,return关键字将a和b相加的结果返回给调用sum 方法的地方。
这样,调用者就可以得到这个求和的结果,并进行后续的处理。
2. 在控制流程中的应用除了作为方法的返回值,return还常用于控制流程中,比如在条件判断或循环中提前结束方法的执行。
我们可以在一个方法中使用return 来检查某个条件是否满足,如果不满足就立即结束方法的执行,并返回到方法的调用者处。
```javapublic void processList(List<String> list, String target) {for (String item : list) {if (item.equals(target)) {System.out.println("Found it!");return;}}System.out.println("Not found.");}```在上面的例子中,如果在list中找到了与target相等的元素,方法就会立即打印"Found it!"并结束执行。
否则,继续遍历list直到结束,打印"Not found."。
3. return在递归调用中的应用在递归调用中,return也扮演着重要的角色。
递归调用是指一个方法在执行过程中调用了自身,常见于解决树的遍历、阶乘计算和斐波那契数列等问题。
50道经典Java逻辑编程题
【程序1】题目:古典问题:有一对兔子,从出生后第3个月起每个月都生一对兔子,小兔子长到第三个月后每个月又生一对兔子,假如兔子都不死,问每个月的兔子总数为多少?1.程序分析:兔子的规律为数列1,1,2,3,5,8,13,21....【程序2】题目:判断101-200之间有多少个素数,并输出所有素数。
1.程序分析:判断素数的方法:用一个数分别去除2到sqrt(这个数),如果能被整除,则表明此数不是素数,反之是素数。
【程序3】题目:打印出所有的"水仙花数",所谓"水仙花数"是指一个三位数,其各位数字立方和等于该数本身。
例如:153是一个"水仙花数",因为153=1的三次方+5的三次方+3的三次方。
1.程序分析:利用for循环控制100-999个数,每个数分解出个位,十位,百位。
【程序4】题目:将一个正整数分解质因数。
例如:输入90,打印出90=2*3*3*5。
程序分析:对n进行分解质因数,应先找到一个最小的质数k,然后按下述步骤完成:(1)如果这个质数恰等于n,则说明分解质因数的过程已经结束,打印出即可。
(2)如果n <> k,但n能被k整除,则应打印出k的值,并用n除以k的商,作为新的正整数你n,重复执行第一步。
(3)如果n不能被k整除,则用k+1作为k的值,重复执行第一步。
【程序5】题目:利用条件运算符的嵌套来完成此题:学习成绩> =90分的同学用A表示,60-89分之间的用B表示,60分以下的用C表示。
1.程序分析:(a> b)?a:b这是条件运算符的基本例子。
【程序6】题目:输入两个正整数m和n,求其最大公约数和最小公倍数。
1.程序分析:利用辗除法。
【程序7】题目:输入一行字符,分别统计出其中英文字母、空格、数字和其它字符的个数。
1.程序分析:利用while语句,条件为输入的字符不为'\n '.【程序8】题目:求s=a+aa+aaa+aaaa+aa...a的值,其中a是一个数字。
java递归详解
java递归详解递归是一种常见的编程技巧,它在解决问题时通过调用自身来实现。
在Java中,递归是一种强大而灵活的工具,可以用于解决各种问题。
本文将详细介绍Java递归的原理、应用场景以及一些注意事项。
首先,让我们来了解递归的原理。
递归函数是一种特殊的函数,它在执行过程中会调用自身。
递归函数通常包含两个部分:基本情况和递归调用。
基本情况是递归函数停止调用自身的条件,而递归调用是递归函数在满足基本情况之前一直调用自身。
递归函数的执行过程可以用一个栈来模拟。
每次递归调用时,函数的局部变量和参数都会被保存在栈中,直到满足基本情况时才会逐个弹出栈。
这种栈的结构被称为递归栈。
递归在解决问题时具有很大的灵活性。
它可以用于解决各种问题,如计算阶乘、斐波那契数列、二叉树遍历等。
下面我们以计算阶乘为例来说明递归的应用。
计算阶乘是一个经典的递归问题。
阶乘的定义是n的阶乘等于n乘以(n-1)的阶乘,其中0的阶乘定义为1。
我们可以使用递归函数来计算阶乘。
```javapublic class Factorial {public static int factorial(int n) {if (n == 0) {return 1;} else {return n * factorial(n - 1);}}public static void main(String[] args) {int n = 5;int result = factorial(n);System.out.println("The factorial of " + n + " is " + result);}}```在上面的代码中,factorial函数是一个递归函数。
当n等于0时,满足基本情况,函数返回1。
否则,函数调用自身,并将n减1作为参数传递给递归调用。
最终,递归函数的返回值是n乘以(n-1)的阶乘。
递归函数的使用需要注意一些问题。
java中递归例子
java中递归例子递归是一种在编程中常用的技巧,它可以通过调用自身来解决问题。
在Java中,递归可以应用于各种问题,从简单的数学运算到复杂的数据结构操作。
下面将列举10个不同的Java递归例子,每个例子都将详细介绍递归的原理和实现方式。
1. 阶乘计算阶乘是一个常见的数学运算,表示从1到给定数字n的连续乘积。
递归可以用来计算阶乘,通过将问题分解为更小的子问题,最终得到结果。
例如,计算5的阶乘可以表示为:5! = 5 * 4 * 3 * 2 * 1。
2. 斐波那契数列斐波那契数列是一个经典的递归问题,其中每个数字是前两个数字之和。
例如,斐波那契数列的前几个数字是:0, 1, 1, 2, 3, 5, 8, 13, 21, 34, ...3. 数组求和递归可以用来计算数组中所有元素的和。
通过将数组分解为更小的子数组,并将每个子数组的和累加起来,我们可以得到整个数组的总和。
4. 数组反转递归可以用来反转一个数组。
通过将数组的第一个元素与最后一个元素交换,并递归地对剩余的子数组进行反转,我们可以得到整个数组的反转结果。
5. 链表反转递归可以用来反转一个链表。
通过将链表的头节点与剩余的子链表进行反转,并将头节点的next指针指向已反转的子链表的末尾,我们可以得到整个链表的反转结果。
6. 树的遍历递归可以用来实现树的遍历算法,包括前序遍历、中序遍历和后序遍历。
通过递归地遍历树的左子树和右子树,我们可以按照指定的顺序访问树的所有节点。
7. 字符串反转递归可以用来反转一个字符串。
通过将字符串的第一个字符与最后一个字符交换,并递归地对剩余的子字符串进行反转,我们可以得到整个字符串的反转结果。
8. 汉诺塔问题汉诺塔问题是一个经典的递归问题,其中有三个柱子和一组圆盘,圆盘按照从小到大的顺序堆叠在柱子上。
目标是将所有圆盘从一个柱子移动到另一个柱子,同时遵循以下规则:每次只能移动一个圆盘,大圆盘不能叠在小圆盘上。
9. 排列组合递归可以用来生成给定集合的所有排列或组合。
递归的几个经典例子
递归的⼏个经典例⼦注意:构造⽅法不可递归,否则是⽆限创建对象;递归的⼏个经典例⼦:1.HannoiTower1import java.util.Scanner;2public class HanoiTower{3//level代表盘⼦个数;三个char类型代表柱⼦4public static void moveDish(int level, char from, char inter, char to){5if(level == 1){6 System.out.println("从"+from+"移动盘⼦1号到"+to);7 }else{89 moveDish(level-1,from,to,inter);//调⽤⾃⾝10 System.out.println("从"+from+"移动盘⼦"+level+"号到"+to);11 moveDish(level-1,inter,from,to);12 }13 }1415public static void main(String[] args){16 Scanner sc = new Scanner(System.in);17 System.out.println("请输⼊盘⼦个数");18int n = sc.nextInt();19 moveDish(n,'a','b','c');20 }21 }222.sum1import java.util.Scanner;2public class Sum{3public static void main(String[] args){4 Scanner sc = new Scanner(System.in);5 System.out.println("请输⼊n:");6int n = sc.nextInt();7int sum1 = sum(n);8 System.out.println(sum1;9 }1011public static int sum(int n){12if(n == 1){13return 1;14 }else{15return n+sum(n-1);16 }17 }18 }193.factorial1import java.util.Scanner;2public class Factorial{3public static void main(String[] args){4 Scanner sc = new Scanner(System.in);5 System.out.println("请输⼊⼀个⼩于20的整数,我会帮你求出它的阶乘:");6int n = sc.nextInt();7int fac1 = fac(n);8 System.out.println(n+"的阶乘为:"+fac1);9 System.out.println("~看我棒不棒~~");10 }1112public static int fac(int n){13if(n == 1){B14return 1;15 }else{16return n*fac(n-1);17 }18 }19 }204.sumFactorial1import java.util.Scanner;2public class SumFactorial{3public static void main(String[] args){4 Scanner sc = new Scanner(System.in);5 System.out.println("请输⼊⼀个⼩于20的整数:"); 6int n = sc.nextInt();7int sf = sumFac(n);8 System.out.println(sf);9 }10//阶乘和的累加11public static int sumFac(int n){12if(n == 1){13return 1;14 }else{15return fac(n)+sumFac(n-1);16 }17 }18//求阶乘19public static int fac(int n){20if(n == 1){21return 1;22 }else{23return n*fac(n-1);24 }25 }26 }5.使⽤递归,遍历 1 ⾄100之间的每个数字1public class Number{2public static void main(String[] args){3 iterator(100);4 }56public static void iterator(int n){7if(n >= 1){8 System.out.print(n+"\t");9 n--;10 iterator(n);11 }1213 }14 }151617。
递归算法的例子
递归算法的例子
1. 计算阶乘不就是个很好的例子嘛!比如计算 5 的阶乘,5! 不就是
5×4×3×2×1 嘛,这就是通过不断用较小的数的阶乘来计算呀,这多有意思啊!
2. 斐波那契数列呀!就像兔子繁殖一样神奇,前两个数相加得到下一个数,是不是很特别?这就是典型的递归算法呀!
3. 走迷宫的时候,你可以用递归算法来试着找路呀!哎呀,要是不这样试试,怎么能找到出口呢?
4. 汉诺塔问题啊,把那些盘子移来移去,不就是递归在发挥作用嘛,神奇吧!
5. 二叉树的遍历,就像是在森林里探索一样,一层一层地深入,这不是递归算法在帮忙嘛!
6. 画分形图形的时候,你看那美丽又复杂的图案,都是递归算法创造出来的呀,哇塞!
7. 分解一个大问题成小问题,再解决小问题,这不就是递归嘛,就像拆礼物一样,一层一层去发现惊喜!
8. 你想想,电脑下棋的时候,不也是用递归算法来分析各种走法吗,真的超厉害的!
总之,递归算法在好多地方都大显身手呢,它让很多复杂的事情变得简单又有趣,能创造出很多神奇的效果呀!。
java进阶知识--Lambda表达式、递归
java进阶知识--Lambda表达式、递归⼀、Lambda表达式 1.1 概述 Lambda表达式是JDK 1.8的重量级新特性,它强调做什么,⽽不是以什么形式去做,或者说它强调结果,⽽不是过程。
⽽这种思想我们称之为函数式编程思想。
函数式编程思想与⾯向对象思想的对⽐: ⾯向对象的思想: 做⼀件事情,找⼀个能解决这个事情的对象,调⽤对象的⽅法,完成事情。
函数式编程思想: 只要能获取到结果,谁去做的,怎么做的都不重要,重视的是结果,不重视过程。
Lambda的使⽤前提1. 使⽤Lambda必须具有接⼝,且要求接⼝中有且仅有⼀个抽象⽅法。
(有且仅有⼀个抽象⽅法的接⼝,称为“函数式接⼝”。
)⽆论是JDK内置的Runnable、Comparator接⼝还是⾃定义的接⼝,只有当接⼝中的抽象⽅法存在且唯⼀时,才可以使⽤Lambda。
2. 使⽤Lambda必须具有上下⽂推断。
也就是⽅法的参数或局部变量类型必须为Lambda对应的接⼝类型,才能使⽤Lambda作为该接⼝的实例。
1.2 体验Lambda的更优写法 传统写法 当需要启动⼀个线程去完成任务时,通常会通过ng.Runnable接⼝来定义任务内容,并使⽤ng.Thread类来启动该线程。
代码如下:public class DemoRunnable { public static void main(String[] args) { // 匿名内部类 Runnable task = new Runnable() { @Override public void run() { // 覆盖重写抽象⽅法 System.out.println("多线程任务执⾏!"); } }; new Thread(task).start(); // 启动线程 }} Lambda的更优写法 借助Java 8的全新语法,上述Runnable接⼝的匿名内部类写法可以通过更简单的Lambda表达式达到等效:public class DemoLambdaRunnable { public static void main(String[] args) { new Thread(() -> System.out.println("多线程任务执⾏!")).start(); // 启动线程 }} 这两段代码的执⾏效果是完全⼀样的,可以在1.8或更⾼的编译级别下通过。
java 递归例子
java 递归例子摘要:1.递归的概念与原理2.Java 中递归的实现方式3.递归的优点与缺点4.常见递归算法举例5.总结正文:1.递归的概念与原理递归是一种函数调用自身的技术,它是一种非常强大的编程技巧,可以使代码更加简洁、优雅。
递归的原理是当函数遇到某个特定条件时,不再继续执行当前函数,而是调用自身来解决更小的子问题,直到子问题被解决,再返回原函数继续执行。
2.Java 中递归的实现方式在Java 中,实现递归的方法非常简单,只需在函数中调用自身即可。
以下是一个简单的递归函数示例:```javapublic class Main {public static void main(String[] args) {System.out.println(factorial(5));}public static int factorial(int n) {if (n == 1) {return 1;} else {return n * factorial(n - 1);}}}```在这个例子中,我们定义了一个名为factorial 的递归函数,它接受一个整数参数n,并计算n 的阶乘。
当n 等于1 时,函数返回1;否则,函数返回n 乘以n-1 的阶乘,这是通过调用自身实现的。
3.递归的优点与缺点递归的优点是代码简洁,易于理解。
递归算法通常非常直观,因为它们直接解决了问题本身,而不是通过复杂的逻辑绕过问题。
然而,递归也有其缺点。
首先,递归会导致函数调用栈的深度增加,可能会导致栈溢出,尤其是在处理大型问题时。
其次,递归可能会导致代码执行效率低下,因为函数调用自身需要额外的开销。
4.常见递归算法举例以下是一些常见的递归算法示例:- 阶乘计算:`n * factorial(n - 1)`- 汉诺塔问题:`print(n - 1) + print(n - 2) + print(n - 3)`- 斐波那契数列:`F(n) = F(n - 1) + F(n - 2)`- 八皇后问题:`print(n - 1) + print(n - 2) +...+ print(0)`5.总结递归是一种强大的编程技巧,可以使代码更加简洁、优雅。
java 递归满足条件直接跳出整个方法
java 递归满足条件直接跳出整个方法(原创实用版4篇)《java 递归满足条件直接跳出整个方法》篇1在Java 中,递归方法可以通过判断条件来跳出整个方法。
这通常是通过在递归方法中使用`return` 语句来实现的。
当满足特定条件时,直接返回即可跳出递归。
以下是一个简单的递归方法示例,该方法计算阶乘(n! = n * (n-1) * (n-2) *... * 1)。
```javapublic int factorial(int n) {if (n == 0 || n == 1) {return 1;}return n * factorial(n - 1);}```在这个例子中,当`n` 等于0 或1 时,条件满足,方法直接返回1。
这意味着递归过程将在这些条件下停止,从而避免了无限递归导致的Stack Overflow。
《java 递归满足条件直接跳出整个方法》篇2在Java 中,递归方法满足条件后直接跳出整个方法,可以通过在递归方法中添加一个标志变量来实现。
这个标志变量在满足条件时被设置为true,递归方法会在下一次调用前检查这个标志变量,如果为true,则直接返回。
下面是一个简单的递归方法示例,用于计算阶乘:```javapublic class Factorial {public static void main(String[] args) {int n = 5;int result = factorial(n);System.out.println("阶乘" + n + "! = " + result);}public static int factorial(int n) {if (n == 0 || n == 1) {return 1;}int result = 1;for (int i = 2; i <= n; i++) {result *= i;}return result;}}```如果我们想在满足条件时直接跳出整个方法,可以在递归方法中添加一个标志变量,如下所示:```javapublic class Factorial {public static void main(String[] args) {int n = 5;boolean isCancelled = false;int result = factorial(n, isCancelled);if (!isCancelled) {System.out.println("阶乘" + n + "! = " + result);}}public static int factorial(int n, boolean isCancelled) {if (n == 0 || n == 1) {return 1;}int result = 1;for (int i = 2; i <= n &&!isCancelled; i++) {result *= i;}if (isCancelled) {return 0;return result;}}```在这个修改后的示例中,我们添加了一个名为`isCancelled` 的标志变量,并将其传递给递归方法。
java递归获取某个父节点下面的所有子节点
java递归获取某个⽗节点下⾯的所有⼦节点package com.demo.web.test;import java.util.ArrayList;import java.util.HashMap;import java.util.List;import java.util.Map;import java.util.Objects;import com.demo.web.model.Menu;import com.google.gson.Gson;public class Test7 {private static List<Menu> treeList = new ArrayList<>(); //全局变量public static void main(String[] args) {// List<Menu> menuList=new ArrayList<Menu>();List<Menu> pidList=new ArrayList<Menu>();Menu mu=new Menu();mu.setId(1);pidList.add(mu);mu.setName("⽬录");mu.setParentid("0");Menu mu1=new Menu();mu1.setId(2);mu1.setName("⽬录1");mu1.setParentid("1");Menu mu2=new Menu();mu2.setId(3);mu2.setName("⽬录2");mu2.setParentid("1");Menu mu3=new Menu();mu3.setId(4);mu3.setName("⽬录3");mu3.setParentid("1");//⽬录3下⼦节点Menu mu4=new Menu();mu4.setId(5);mu4.setName("⽬录4");mu4.setParentid("4");treeList.add(mu);treeList.add(mu1);treeList.add(mu2);treeList.add(mu3);treeList.add(mu4);//pidSystem.out.println("pidList:-------------------"+pidList);List<Menu> tree = getTree(treeList,pidList);for (Menu menu : tree) {System.out.println(menu.getId()+" ------- "+menu.getName()+" "+menu.getChildren().get(2).getChildren());}System.out.println("7715-=-----------"+tree.get(0).getChildren());Gson gson = new Gson();//import com.google.gson.Gson;String result = gson.toJson(tree);//pojoSystem.out.println("我看看0---------"+result);}public static List<Menu> getTree(List<Menu> menu,List<Menu> parentList) {//先获取到所有数据// treeList=MenuMapper.getList();if(menu==null) return null;//获取到所有⼀级节点// List<Menu> parentList = this.MenuMapper.findParentList();List<Menu> list = new ArrayList<>();if(parentList != null){for (int i = 0; i < parentList.size(); i++) {list.add(recursiveTree(parentList.get(i).getId()));}}return list;}/*** 递归算法解析成树形结构* @param cid*/public static Menu recursiveTree(Integer cid) {Menu node = getMenuById(cid);List<Menu> childTreeNodes = getChildTreeById(cid);for(Menu child : childTreeNodes){Menu n = recursiveTree(child.getId());List<Menu> list = new ArrayList<Menu>();list.add(n);System.out.println(node.getChildren());if (node.getChildren()==null) {List<Menu> li = new ArrayList<Menu>();node.setChildren(li);}// node.setChildren(list);node.getChildren().add(n);}return node;}/*** 根据CID查询节点对象*/public static Menu getMenuById(Integer cid){Map map = getTreeMap();return (Menu) map.get(cid);}/*** ⼀次性取所有数据,为了减少对数据库查询操作* @return*/public static Map getTreeMap(){Map map = new HashMap<Integer, Menu>();if(null != treeList){for(Menu d : treeList){map.put(d.getId(), d);}}return map;}/*** 根据⽗节点CID获取所有了节点*/public static List<Menu> getChildTreeById(Integer cid){List<Menu> list = new ArrayList<>();if(null != treeList){for (Menu d : treeList) {if(null != cid){if (cid.equals(Integer.valueOf(d.getParentid()))) { list.add(d);}}}}return list;}}。
递归算法经典题目
递归算法经典题目递归算法是一种非常强大的编程技术,它能够解决一些复杂的问题,将它们分解为更小的子问题。
以下是一些经典的递归算法题目:1. 斐波那契数列:这是一个经典的递归问题,斐波那契数列中的每个数字都是前两个数字的和。
例如,0, 1, 1, 2, 3, 5, 8, 13, 21... 编写一个函数来计算斐波那契数列中的第n个数字。
2. 阶乘:阶乘是一个数的所有小于及等于该数的正整数的乘积。
例如,5的阶乘(记作5!)是5 4 3 2 1 = 120。
编写一个函数来计算一个数的阶乘。
3. 二分搜索:二分搜索是一种在排序数组中查找特定元素的搜索算法。
编写一个函数,该函数使用二分搜索在给定的排序数组中查找特定的元素。
4. 回溯算法:回溯算法用于解决决策问题,例如八皇后问题。
在这个问题中,我们需要在一个8x8棋盘上放置8个皇后,使得任何两个皇后都不在同一行、同一列或同一对角线上。
编写一个使用回溯算法解决八皇后问题的函数。
5. 合并排序:合并排序是一种分治算法,它将一个大的列表分成两个较小的子列表,对子列表进行排序,然后将它们合并成一个已排序的列表。
编写一个使用递归实现合并排序的函数。
6. 快速排序:快速排序也是一种分治算法,它选择一个"基准"元素,然后将所有比基准小的元素放在其左边,所有比基准大的元素放在其右边。
然后对左右两个子列表进行快速排序。
编写一个使用递归实现快速排序的函数。
7. 深度优先搜索(DFS):这是一种用于遍历或搜索树或图的算法。
这个算法会尽可能深地搜索树的分支。
当节点v的所在边都己被探寻过,搜索将回溯到发现节点v的那条边的起始节点。
这一过程一直进行到已发现从源节点可达的所有节点为止。
如果还存在未被发现的节点,则选择其中一个作为源节点并重复以上过程,整个进程反复进行直到所有节点都被访问为止。
编写一个使用递归实现深度优先搜索的函数。
这些题目都可以帮助你理解和应用递归算法。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
java递归的经典例子
1。
汉诺塔
这是递归的超经典的例子,几乎每本程序设计书上谈到递归都会介绍。
具体情景不再赘述。
以我上述的方法观之:(1)递归的出口在于disk数为一的时候(2)向出口逼近:如果不是一,是n ,则我们先挪动上面n-1块disk,等上面挪完,即递归返回的时候,我们挪动最底下的disk。
仅仅如此,一个貌似十分复杂的问题就解决了,因为挪动那n-1块disk的时候,会继续向上减少,直到disk的数量为一为止。
下面给出java程序编码(已测试过,运行正常):
import javax.swing.JOptionPane;
public class Hanoi {
private static final String DISK_B = "diskB";
private static final String DISK_C = "diskC";
private static final String DISK_A = "diskA";
static String from=DISK_A;
static String to=DISK_C;
static String mid=DISK_B;
public static void main(String[] args) {
String input=JOptionPane.showInputDialog("please input the number of the disks you want me move.");
int num=Integer.parseInt(input);
move(num,from,mid,to);
}
private static void move(int num, String from2, String mid2, String to2) {
if(num==1){
System.out.println("move disk 1 from "+from2+" to "+to2);
}
else {
move(num-1,from2,to2,mid2);
System.out.println("move disk "+num+" from "+from2+" to "+to2);
move(num-1,mid2,from2,to2);
}
}
}
2。
这是一个排列的例子,它所做的工作是将输入的一个字符串中的所有元素进行排序并输出,例如:你给出的参数是"abc" 则程序会输出:
abc
acb
bac
bca
cab
cba
(1)算法的出口在于:low=high也就是现在给出的排列元素只有一个时。
(2)算法的逼近过程:先确定排列的第一位元素,也就是循环中i所代表的元素,
然后low+1开始减少排列元素,如此下去,直到low=high
public static void permute(String str) {
char[] strArray = str.toCharArray();
permute(strArray, 0, strArray.length - 1);
}
public static void permute(char[] list, int low, int high) {
int i;
if (low == high) {
String cout = "";
for (i = 0; i <= high; i++)
cout += list[i];
System.out.println(cout);
} else {
for (i = low; i <= high; i++) {
char temp = list[low];
list[low] = list[i];
list[i] = temp;
permute(list, low + 1, high);
temp = list[low];
list[low] = list[i];
list[i] = temp;
}
}
}
3.这是一个组合的例子,与上述的例子相似,只是它所做的工作是,输出所给字符串中制定数目的元素的组合种类
(1)程序出口在于n=1,此时只要输出目标数组的所有元素即可
(2)逼近过程,当n>1的时候,我们先取第一个元素放入目标数组中,然后n-1,如此下去,最后出来。
import javax.swing.JOptionPane;
public class Combination {
/**
* @param args
*/
public static void main(String[] args) {
String input = JOptionPane
.showInputDialog("please input your String: ");
String numString = JOptionPane
.showInputDialog("please input the number of your Combination: ");
int num = Integer.parseInt(numString);
Combine(input, num);
}
private static void Combine(String input, int num) {
char[] a = input.toCharArray();
String b = "";
Combine(a, num, b, 0, a.length);
}
private static void Combine(char[] a, int num, String b, int low, int high) {
if (num == 0) {
System.out.println(b);
} else {
for (int i = low; i < a.length; i++) {
b += a[i];
Combine(a, num - 1, b, i+1, a.length);
b=b.substring(0, b.length()-1);
}
}
}
}。