Java算法之递归打破及在真实项目中的使用实例
开心一笑
刚才领导问开发:“你觉得这个项目的最大风险是什么”,开发说:"加班猝死" , 气氛尴尬了一分钟!!!
提出问题
1.递归算法简单复习 2.如何实现递归算法与真实项目接口??? 3.如何打破递归算法???
解决问题
1.首先练习下网上一些递归经典题
package com.hwy.test; /**
* 递归函数测试
* Created by Ay on 2016/7/2.
*/
public class RecursionTest { public static void main(String[] args) { /** 利用递归函数实现1 + 2 + 3 ... 100 **/
int sum = Sum(100);
System.out.println("the 1 + 2 + 3 ... 100 =" + sum); } /** 获得总和 **/
public static int Sum(int num){ if(num > 0){
return num +Sum(num-1);
}
return 0;
} }
结果:
the 1 + 2 + 3 ... 100 =5050
2.求最大公约数
package com.hwy.test; /**
* 递归函数测试
* Created by Ay on 2016/7/2.
*/
public class RecursionTest { public static void main(String[] args) {
/** GCD最大公约数简称 **/
GCD(36,2);
} public static int GCD(int a,int b){ if(a == b){
System.out.println("最大公约数为: " + a);
}else{
/** 用2个数相减的绝对值和和2个数的最小值一直比较,直到相等为止 **/
GCD(Math.abs(a -b),Math.min(a,b));
}
return 0;
} }
3.我们的重点不是这个,现在介绍在真实项目中的递归如何使用
业务场景是这样的:从数据库中查询一颗树,我现在用代码模拟,具体可看下面的代码,我们要做的是遍历该树,如果该树中的节点id等于我们传入的id,终止遍历该树。
package com.hwy.test; import com.alibaba.fastjson.JSONObject;
import org.apache.commons.lang3.StringUtils;
import java.util.ArrayList;
import java.util.List; /**
* 节点
*/
class Node{ /** 节点id **/
private String id;
/** 父节点id **/
private String pid;
/** 节点名称 **/
private String name;
/** 子节点 **/
private List<Node> childen;
/** 构造函数 **/
public Node(){}
/** 构造函数 **/
public Node(String id,String pid,String name,List<Node> nodes){
this.id = id;
this.pid = pid;
this.name = name;
this.childen = nodes;
} public String getId() {
return id;
} public void setId(String id) {
this.id = id;
} public String getPid() {
return pid;
} public void setPid(String pid) {
this.pid = pid;
} public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} public List<Node> getChilden() {
return childen;
} public void setChilden(List<Node> childen) {
this.childen = childen;
}
} /**
* 递归函数测试
* Created by Ay on 2016/7/2.
*/
public class RecursionTest { public static String nodeName = ""; public static void main(String[] args) {
/** 初始化树模型 **/
Node node = initTreeModel();
/** 节点id **/
getNodeId(node, "CC2");
} /**
*
* @param node
* @return
*/
public static String getNodeId(Node node,String myId){
/** 打印每次遍历节点信息 **/
System.out.println("--->>>" + node.getId());
/** 判断是否是我们苦苦寻找的id **/
if(StringUtils.isNotEmpty(myId) && myId.equals(node.getId())){
nodeName = node.getName();
return nodeName;
}else{
if(null != node.getChilden() && node.getChilden().size() >0){
for(Node n:node.getChilden()){
/** 这里是重点中的重点,如果nodeName不为空,恭喜你找到了,返回该值,
递归函数就会一层一层的返回,每一层的返回都会进行该判断,但我们已经找到
值了,所有递归相当于被打破了**/
if(StringUtils.isNotEmpty(nodeName)){
return nodeName;
}else{
/** 继续递归 **/
getNodeId(n, myId);
} }
}
return null;
}
} /**
* 初始化树模型
* @return
*/
public static Node initTreeModel(){
/** 构造第三层节点 **/
Node AAA1 = new Node("AAA1","AA1","AAA1",null);
Node AAA2 = new Node("AAA2","AA1","AAA2",null);
Node AAA3 = new Node("AAA3","AA1","AAA3",null);
Node AAA4 = new Node("AAA4","AA1","AAA4",null);
List<Node> AAANodes = new ArrayList<>();
AAANodes.add(AAA1);
AAANodes.add(AAA2);
AAANodes.add(AAA3);
AAANodes.add(AAA4); Node AA1 = new Node("AA1","A","AA1",null);
Node AA2 = new Node("AA2","A","AA2",null);
Node AA3 = new Node("AA3","A","AA3",null); List<Node> AANodes = new ArrayList<>();
AANodes.add(AA1);
AANodes.add(AA2);
AANodes.add(AA3); Node A = new Node("A","0","A",null); AA1.setChilden(AAANodes);
A.setChilden(AANodes); Node BBB1 = new Node("BBB1","BB1","BBB1",null);
Node BBB2 = new Node("BBB2","BB1","BBB2",null);
Node BBB3 = new Node("BBB3","BB1","BBB3",null);
Node BBB4 = new Node("BBB4","BB1","BBB4",null); List<Node> BBBNode = new ArrayList<>();
BBBNode.add(BBB1);
BBBNode.add(BBB2);
BBBNode.add(BBB3); BBBNode.add(BBB4); Node BB1 = new Node("BB1","B","BB1",null);
Node BB2 = new Node("BB2","B","BB2",null);
Node BB3 = new Node("BB3","B","BB3",null); List<Node> BBNode = new ArrayList<>();
BBNode.add(BB1);
BBNode.add(BB2);
BBNode.add(BB3); Node B = new Node("B","0","B",null); B.setChilden(BBNode);
BB1.setChilden(BBBNode); Node CC1 = new Node("CC1","C","CC1",null);
Node CC2 = new Node("CC2","C","CC2",null);
Node CC3 = new Node("CC3","C","CC3",null);
List<Node> CCNode = new ArrayList<>();
CCNode.add(CC1);
CCNode.add(CC2);
CCNode.add(CC3); Node C = new Node("C","0","C",null);
C.setChilden(CCNode); List<Node> nodes = new ArrayList<>();
nodes.add(A);
nodes.add(B);
nodes.add(C); Node root = new Node("0",null,"root",nodes);
/** 打印json数据 **/
System.out.println(JSONObject.toJSON(root).toString());
return root;
}
}
树形结构数据如下:
树形结构数据
重要的话讲三遍:
这里是重点中的重点,如果nodeName不为空,恭喜你找到了,返回该值,递归函数就会一层一层的返回,每一层的返回都会进行该判断,但我们已经找到值了,所有递归相当于被打破了
这里是重点中的重点,如果nodeName不为空,恭喜你找到了,返回该值,递归函数就会一层一层的返回,每一层的返回都会进行该判断,但我们已经找到值了,所有递归相当于被打破了
读书感悟
来自《风月俏佳人》
- 维维安: 小时候,当我做错事的时候,我妈妈经常把我关在楼阁里。然后我就会感觉自己是一个被恶毒的女王囚禁的公主。总相信会有一个骑士突然出现,手里挥舞着剑,骑着白马上来,把我从楼阁中营救出来……但一直没有出现,每次幻想中,骑士确实对我说,“来吧,亲爱的,我会把你带入一座雄伟的华厦。”
- 放弃这么美好的东西一定很困难
其他
如果有带给你一丝丝小快乐,就让快乐继续传递下去,欢迎转载,点赞,顶,欢迎留下宝贵的意见,多谢支持!
Java算法之递归打破及在真实项目中的使用实例的更多相关文章
- java使用elasticsearch进行模糊查询-已在项目中实际应用
java使用elasticsearch进行模糊查询 使用环境上篇文章本人已书写过,需要maven坐标,ES连接工具类的请看上一篇文章,以下是内容是笔者在真实项目中运用总结而产生,并写的是主要方法和思路 ...
- JAVA算法之递归
Ⅰ.三角数字 首先我们来看一组数字:1,3,6,10,15,21.....,在这个数列中第n项是由n-1项加n得到的,这个序列中的数字称为三角数字因为他们可以形象化地表示成一个三角形排列.如下图 通过 ...
- memcached真实项目中的应用
上一篇memcached介绍及基本使用介绍了memcached的一些基本概念和一个范例.这一篇将介绍一个memcached在实际项目中的应用
- 真实项目中VS2015中自建T4模板生成文件的使用
有可能许多小伙伴们发现,vs2015和2012的自带T4模板中的.tt文件改变非常之多,如果仅仅copyEF系统自己生成的模板文件,那可累了.以下是我自己整理的在2012和2015中都可以试用的代码. ...
- 真实项目中 ThreadLocal 的妙用
一.什么是 ThreadLocal ThreadLocal 提供了线程的局部变量,每个线程都可以通过 set() 和 get() 来对这个局部变量进行操作,但不会和其他线程的局部变量冲突,实现了线程间 ...
- 【一起学设计模式】观察者模式实战:真实项目中屡试不爽的瓜娃EventBus到底如何实现观察者模式的?
申明 本文章首发自本人公众号:壹枝花算不算浪漫,如若转载请标明来源! 感兴趣的小伙伴可关注个人公众号:壹枝花算不算浪漫 22.jpg 前言 之前出过一个设计模式的系列文章,这些文章和其他讲设计模式的文 ...
- Java实现 蓝桥杯VIP 算法提高 递归倒置字符数组
算法提高 递归倒置字符数组 时间限制:1.0s 内存限制:512.0MB 问题描述 完成一个递归程序,倒置字符数组.并打印实现过程 递归逻辑为: 当字符长度等于1时,直接返回 否则,调换首尾两个字符, ...
- JAVA算法系列 快速排序
java算法系列之排序 手写快排 首先说一下什么是快排,比冒泡效率要高,快排的基本思路是首先找到一个基准元素,比如数组中最左边的那个位置,作为基准元素key,之后在最左边和最右边设立两个哨兵,i 和 ...
- JavaScript算法 ,Python算法,Go算法,java算法,系列之【归并排序】篇
常见的内部排序算法有:插入排序.希尔排序.选择排序.冒泡排序.归并排序.快速排序.堆排序.基数排序等.用一张图概括: 归并排序(英语:Merge sort,或mergesort),是创建在归并操作上的 ...
随机推荐
- neo4j-简介,安装
1. Neo4j简介 Neo4j是一个用Java实现的.高性能的.NoSQL图形数据库. Neo4j 使用图(graph)相关的概念来描述数据模型,通过图中的节点和节点的关系来建模. Neo4j完全兼 ...
- 从linux0.11中起动部分代码看汇编调用c语言函数
上一篇分析了c语言的函数调用栈情况,知道了c语言的函数调用机制后,我们来看一下,linux0.11中起动部分的代码是如何从汇编跳入c语言函数的.在LINUX 0.11中的head.s文件中会看到如下一 ...
- C#面向对象设计模式纵横谈——3.Abstract Factory 抽象工厂(创建型模式)
动机(Motivation) 在软件系统中经常面临着“一系列相互依赖的对象”的创建工作,同时,由于需求变化,往往存在更多系列对象的创建工作.如何应对这种变化?如何绕过常规对象的创建,提供一种“封装机制 ...
- 《C编译器剖析》后记
这本书的序言.后记写的都让我很有感触!mark: 后 记 总有曲终人散时,不知不觉我们已经完成了对UCC 编译器的剖析,一路走来,最深的体会仍然是“纸上得来终觉浅,绝知此事要躬行”.按这个道理,理解U ...
- Linux终端使用代理服务器
1.YUM添加代理服务器: [root@localhost /]# vim /etc/yum.conf 添加如下项目: proxy=http://172.16.1.188:8888/2.WGET添加代 ...
- 【原】webp图片牛刀小试
其实今年很早就有接触到webp图片的概念,只是一直没怎么弄.今天在一个小项目中小用了一番.总结总结 采用 what,why,how的方式来总结 what? 什么是webp图片? 维基百科: ...
- form表单的属性标签和练习
form表单的标签 做一个如下图的form表单: 我们的代码如下: <body leftmargin="400px" topmargin="200px"& ...
- Go收藏
Go项目收藏 电子书 1.Go Web 编程 2.Go入门指南(the-way-to-go_ZH_CN) 3.Go语言圣经(中文版) Go by Example 中文 一些Go英文电子书 High P ...
- [C++]for同时遍历两个数组
C++11同时遍历两个数组 #define for2array(x,y,xArray,yArray) \ for(auto x=std::begin(xArray), x##_end=std::end ...
- 消除左递归c语言文法
<程序> -〉 <外部声明> | <函数定义><外部声明> -〉<头文件> | <变量> | <结构体> <头 ...