Java算法之递归打破及在真实项目中的使用实例

开心一笑

刚才领导问开发:“你觉得这个项目的最大风险是什么”,开发说:"加班猝死" , 气氛尴尬了一分钟!!!

提出问题

1.递归算法简单复习 2.如何实现递归算法与真实项目接口??? 3.如何打破递归算法???

解决问题

1.首先练习下网上一些递归经典题

 1 package com.hwy.test;
 2
 3 /**
 4  * 递归函数测试
 5  * Created by Ay on 2016/7/2.
 6  */
 7 public class RecursionTest {
 8
 9     public static void main(String[] args) {
10
11         /** 利用递归函数实现1 + 2 + 3 ... 100  **/
12         int sum = Sum(100);
13         System.out.println("the 1 + 2 + 3 ... 100 =" + sum);
14
15     }
16
17     /** 获得总和 **/
18     public static int Sum(int num){
19
20         if(num > 0){
21             return num +Sum(num-1);
22         }
23         return  0;
24     }
25
26
27 }

结果:

1 the 1 + 2 + 3 ... 100 =5050

2.求最大公约数

 1 package com.hwy.test;
 2
 3 /**
 4  * 递归函数测试
 5  * Created by Ay on 2016/7/2.
 6  */
 7 public class RecursionTest {
 8
 9     public static void main(String[] args) {
10         /** GCD最大公约数简称 **/
11         GCD(36,2);
12     }
13
14     public static int GCD(int a,int b){
15
16         if(a == b){
17             System.out.println("最大公约数为: " + a);
18         }else{
19             /** 用2个数相减的绝对值和和2个数的最小值一直比较,直到相等为止 **/
20             GCD(Math.abs(a -b),Math.min(a,b));
21         }
22         return 0;
23     }
24
25 }

3.我们的重点不是这个,现在介绍在真实项目中的递归如何使用

业务场景是这样的:从数据库中查询一颗树,我现在用代码模拟,具体可看下面的代码,我们要做的是遍历该树,如果该树中的节点id等于我们传入的id,终止遍历该树。

  1 package com.hwy.test;
  2
  3 import com.alibaba.fastjson.JSONObject;
  4 import org.apache.commons.lang3.StringUtils;
  5 import java.util.ArrayList;
  6 import java.util.List;
  7
  8 /**
  9  * 节点
 10  */
 11 class Node{
 12
 13     /** 节点id **/
 14     private String id;
 15     /** 父节点id **/
 16     private String pid;
 17     /** 节点名称 **/
 18     private String name;
 19     /** 子节点 **/
 20     private List<Node> childen;
 21     /** 构造函数 **/
 22     public Node(){}
 23     /** 构造函数 **/
 24     public Node(String id,String pid,String name,List<Node> nodes){
 25         this.id = id;
 26         this.pid = pid;
 27         this.name = name;
 28         this.childen = nodes;
 29     }
 30
 31     public String getId() {
 32         return id;
 33     }
 34
 35     public void setId(String id) {
 36         this.id = id;
 37     }
 38
 39     public String getPid() {
 40         return pid;
 41     }
 42
 43     public void setPid(String pid) {
 44         this.pid = pid;
 45     }
 46
 47     public String getName() {
 48         return name;
 49     }
 50
 51     public void setName(String name) {
 52         this.name = name;
 53     }
 54
 55     public List<Node> getChilden() {
 56         return childen;
 57     }
 58
 59     public void setChilden(List<Node> childen) {
 60         this.childen = childen;
 61     }
 62 }
 63
 64 /**
 65  * 递归函数测试
 66  * Created by Ay on 2016/7/2.
 67  */
 68 public class RecursionTest {
 69
 70     public static String nodeName = "";
 71
 72     public static void main(String[] args) {
 73         /** 初始化树模型 **/
 74         Node node = initTreeModel();
 75         /** 节点id **/
 76         getNodeId(node, "CC2");
 77     }
 78
 79     /**
 80      *
 81      * @param node
 82      * @return
 83      */
 84     public static String getNodeId(Node node,String myId){
 85         /** 打印每次遍历节点信息 **/
 86         System.out.println("--->>>" + node.getId());
 87         /** 判断是否是我们苦苦寻找的id **/
 88         if(StringUtils.isNotEmpty(myId) && myId.equals(node.getId())){
 89             nodeName = node.getName();
 90             return nodeName;
 91         }else{
 92             if(null != node.getChilden() && node.getChilden().size() >0){
 93                     for(Node n:node.getChilden()){
 94                         /** 这里是重点中的重点,如果nodeName不为空,恭喜你找到了,返回该值,
 95                           递归函数就会一层一层的返回,每一层的返回都会进行该判断,但我们已经找到
 96                          值了,所有递归相当于被打破了**/
 97                         if(StringUtils.isNotEmpty(nodeName)){
 98                             return nodeName;
 99                         }else{
100                             /** 继续递归 **/
101                             getNodeId(n, myId);
102                         }
103
104                     }
105             }
106             return null;
107         }
108     }
109
110
111     /**
112      * 初始化树模型
113      * @return
114      */
115     public static Node initTreeModel(){
116         /** 构造第三层节点 **/
117         Node AAA1 = new Node("AAA1","AA1","AAA1",null);
118         Node AAA2 = new Node("AAA2","AA1","AAA2",null);
119         Node AAA3 = new Node("AAA3","AA1","AAA3",null);
120         Node AAA4 = new Node("AAA4","AA1","AAA4",null);
121         List<Node> AAANodes = new ArrayList<>();
122         AAANodes.add(AAA1);
123         AAANodes.add(AAA2);
124         AAANodes.add(AAA3);
125         AAANodes.add(AAA4);
126
127         Node AA1 = new Node("AA1","A","AA1",null);
128         Node AA2 = new Node("AA2","A","AA2",null);
129         Node AA3 = new Node("AA3","A","AA3",null);
130
131         List<Node> AANodes = new ArrayList<>();
132         AANodes.add(AA1);
133         AANodes.add(AA2);
134         AANodes.add(AA3);
135
136         Node A = new Node("A","0","A",null);
137
138         AA1.setChilden(AAANodes);
139         A.setChilden(AANodes);
140
141         Node BBB1 = new Node("BBB1","BB1","BBB1",null);
142         Node BBB2 = new Node("BBB2","BB1","BBB2",null);
143         Node BBB3 = new Node("BBB3","BB1","BBB3",null);
144         Node BBB4 = new Node("BBB4","BB1","BBB4",null);
145
146         List<Node> BBBNode = new ArrayList<>();
147         BBBNode.add(BBB1);
148         BBBNode.add(BBB2);
149         BBBNode.add(BBB3);
150
151         BBBNode.add(BBB4);
152
153         Node BB1 = new Node("BB1","B","BB1",null);
154         Node BB2 = new Node("BB2","B","BB2",null);
155         Node BB3 = new Node("BB3","B","BB3",null);
156
157         List<Node> BBNode = new ArrayList<>();
158         BBNode.add(BB1);
159         BBNode.add(BB2);
160         BBNode.add(BB3);
161
162         Node B = new Node("B","0","B",null);
163
164         B.setChilden(BBNode);
165         BB1.setChilden(BBBNode);
166
167         Node CC1 = new Node("CC1","C","CC1",null);
168         Node CC2 = new Node("CC2","C","CC2",null);
169         Node CC3 = new Node("CC3","C","CC3",null);
170         List<Node> CCNode = new ArrayList<>();
171         CCNode.add(CC1);
172         CCNode.add(CC2);
173         CCNode.add(CC3);
174
175         Node C = new Node("C","0","C",null);
176         C.setChilden(CCNode);
177
178         List<Node> nodes = new ArrayList<>();
179         nodes.add(A);
180         nodes.add(B);
181         nodes.add(C);
182
183         Node root = new Node("0",null,"root",nodes);
184         /** 打印json数据 **/
185         System.out.println(JSONObject.toJSON(root).toString());
186         return root;
187     }
188 }

树形结构数据如下:

树形结构数据

重要的话讲三遍:

这里是重点中的重点,如果nodeName不为空,恭喜你找到了,返回该值,递归函数就会一层一层的返回,每一层的返回都会进行该判断,但我们已经找到值了,所有递归相当于被打破了

这里是重点中的重点,如果nodeName不为空,恭喜你找到了,返回该值,递归函数就会一层一层的返回,每一层的返回都会进行该判断,但我们已经找到值了,所有递归相当于被打破了

读书感悟

来自《风月俏佳人》

  • 维维安: 小时候,当我做错事的时候,我妈妈经常把我关在楼阁里。然后我就会感觉自己是一个被恶毒的女王囚禁的公主。总相信会有一个骑士突然出现,手里挥舞着剑,骑着白马上来,把我从楼阁中营救出来……但一直没有出现,每次幻想中,骑士确实对我说,“来吧,亲爱的,我会把你带入一座雄伟的华厦。”
  • 放弃这么美好的东西一定很困难

其他

如果有带给你一丝丝小快乐,就让快乐继续传递下去,欢迎转载,点赞,顶,欢迎留下宝贵的意见,多谢支持!

时间: 2024-10-24 13:10:55

Java算法之递归打破及在真实项目中的使用实例的相关文章

Android省市区三级联动滚轮选择(真实项目中提取出来的组件)

最近项目要做一个,类似淘宝手机客户端的,选择收货地址的三级联动滚动选择组件,下面是它的大致界面截图: 在IOS中有个叫UIPickerView的选择器,并且在dataSource中定义了UIPickerView的数据源和定制内容,所以用只要熟悉它的基本用法,要实现这么个三级联动滑动选择是挺简单的. 言归正传,今天讨论的是在Android里面如何来实现这么个效果,那么如何实现呢??? 相信部分童鞋首先想到的是android.widget.DatePicker和android.widget.Time

从真实项目中抠出来的设计模式——第三篇:责任链模式

一:现实场景 有时候在开发的过程中,我们经常会根据某个状态的值,写出很多的ifelse逻辑,比如拿项目里面的案例来说,如果当前发送的是彩信,此种状态需要如何给 实体赋值,如果是短信,邮件又是其他方式的赋值,等等此类,这种情况下一般会写出如下if判断,对吧,真实代码如下: 1 if (leaflet.CommunicationtypeEnum.HasFlag(CommunicationTypeEnum.邮件)) 2 { 3 //第三步:动态生成邮件模板 4 var styleInfo = Cach

阿里Java研发三面:说一下你项目中的单点登录是如何实现的?

一.单系统登录机制 1.http无状态协议 web应用采用browser/server架构,http作为通信协议.http是无状态协议,浏览器的每一次请求,服务器会独立处理,不与之前或之后的请求产生关联,这个过程用下图说明,三次请求/响应对之间没有任何联系. 但这也同时意味着,任何用户都能通过浏览器访问服务器资源,如果想保护服务器的某些资源,必须限制浏览器请求:要限制浏览器请求,必须鉴别浏览器请求,响应合法请求,忽略非法请求:要鉴别浏览器请求,必须清楚浏览器请求状态.既然http协议无状态,那就

从真实项目中抠出来的设计模式——第二篇:过滤器模式

一:实际场景介绍 我们在给用户做订单催付通知的时候,会有这样的一种场景,用户在系统后台设置一组可以催付的规则,比如说订单金额大于xx元,非黑名单用户,来自 哪个地区,已购买过某个商品,指定某个营销活动的人等等这样的条件,如果这时用户在淘宝上下了一个订单,那程序要判断的就是看一下此订单是否满足这 些规则中的某一个,如果满足,我们给他发送催付通知,这种场景是很多做CRM的同学都会遇到的问题,那针对这种场景,如何更好的规划业务逻辑呢? 二:普通的编程代码 在这里我们就不考虑多筛选条件下的性能,而只从代

真实项目中,模块化javascript

为了和10年前的老项目在技术上和逻辑上完全抽离,可以通过模块化js的方式和老项目进行衔接: //竞品车系相关js //JS 模块 var jingpinMain = { //下拉框数量 selectCount : 1, //相关使用api URL: { //获取全部品牌 getCarBrandUrl: function () { return "/NewPost/GetCarBrand/"; }, //品牌获取车系url getCarSericesUrl: function () {

轨迹系列——记某真实项目中轨迹存储改造方案

文章版权由作者李晓晖和博客园共有,若转载请于明显处标明出处:http://www.cnblogs.com/naaoveGIS/ 1.    方案目标 该方案需要满足以下几点: 支持人员当天轨迹快速获取(查询). 支持轨迹高并发读.写(实际项目中轨迹高并发读情况很少). 保证所有(历史)轨迹数据的完整性.不丢失. 2.方案探讨详细描述 2.1支持轨迹快速查询--轨迹日志文件方案 海量数据高效存储.查询,这个场景本身是比较适合NoSQL数据库运用的,但是考虑到该方案实施的难度(对工程实施.维护.研发

真实项目中VS2015中自建T4模板生成文件的使用

有可能许多小伙伴们发现,vs2015和2012的自带T4模板中的.tt文件改变非常之多,如果仅仅copyEF系统自己生成的模板文件,那可累了.以下是我自己整理的在2012和2015中都可以试用的代码. <#@ template language="C#" debug="false" hostspecific="true"#> <#@ include file="EF.Utility.CS.ttinclude"

真实项目中 ThreadLocal 的妙用

一.什么是 ThreadLocal ThreadLocal 提供了线程的局部变量,每个线程都可以通过 set() 和 get() 来对这个局部变量进行操作,但不会和其他线程的局部变量冲突,实现了线程间的据隔离. 简单讲:一个获取用户的请求线程 A,如果向 ThreadLocal 填充变量 AValue(只能被线程 A 操作),该变量对其他获取用户的请求线程 B.C...是隔离的. 最简单的使用方式: 类似一次 HTTP 请求线程中,利用 ThreadLocal 存储 Cookie 对象,进行状态

VUE真实项目中常用的生命周期和参数

<template> <div class="first-app"> {{msg}} <br/> {{msg1}} <Confin text='注册' @message="getMeaasge"></Confin> </div> </template> <script> import Confin from '@/components/sub/Confin'; expor