java递归和反向递归
1. 递归查询树tree结构有两种做法:
第一种,递归查询数据库结构,
第二种,一次性将数据库表中的所有数据查出来,然后再递归查出来的list集合,
第一种做法适合数据量较少的tree结构,因为要一直查询数据库数据量大时速度回相对较慢,所以数据量大时建议使用第二种方法,如图1所示是一个常见的树tree结构
图1
2. 反向递归(逆向递归)查询树tree结构根据关键字过滤数据
大家有么有遇到过这个问题:我想要根据关键字过滤查询出相关数据和它的上级结构,得到图1所示结果,可往往不知道怎么做,查不出上级结构总是得到图3类似的结构,要解决这个比较常见的问题就要用到反向递归的算法,网上我那个网搜不到类似的解决方案,本人一时兴趣来了,做了一套递归和反递归的解决方案,简单易懂,大家可以相互交流一下
图2
图3
3.示例代码
- /**
- * 说明方法描述:将list转为树tree结构
- *
- * @param allRrecords
- * @return
- * @time 2016年5月10日 下午6:00:35
- * @author yangdong
- */
- public List<Record> useListRecordToTree(List<Record> allRrecords) {
- List<Record> listParentRecord = new ArrayList<Record>();
- List<Record> listNotParentRecord = new ArrayList<Record>();
- // 第一步:遍历allRrecords保存所有数据的uuid用于判断是不是根节点
- Map<String, String> mapAllUuid = new HashMap<String, String>();
- Map<String, Record> allRecordMap = new HashMap<String, Record>();
- for (Record record : allRrecords) {
- mapAllUuid.put(record.getStr("uuid"), record.getStr("uuid"));
- allRecordMap.put(record.getStr("uuid"), record);
- }
- // 第二步:遍历allRrecords找出所有的根节点和非根节点
- if (allRrecords != null && allRrecords.size() > 0) {
- for (Record record : allRrecords) {
- if (StringUtil.isBlank(record.getStr("parent_uuid"))
- || !mapAllUuid.containsKey(record.getStr("parent_uuid"))) {
- listParentRecord.add(record);
- } else {
- listNotParentRecord.add(record);
- }
- }
- }
- // 第三步: 递归获取所有子节点
- if (listParentRecord.size() > 0) {
- for (Record record : listParentRecord) {
- // 添加所有子级
- record.set("childs", this.getTreeChildRecord(listNotParentRecord, record.getStr("uuid")));
- }
- }
- return listParentRecord;
- }
- /**
- * 说明方法描述:使list转换为树并根据关键字和节点名称过滤
- *
- * @param allRecords 所有节点
- * @param keywords 要过滤的关键字
- * @param filterFields 要过滤的字段
- * @return
- * @time 2016年5月19日 下午3:27:32
- * @author yangdong
- */
- public List<Record> useListRecordToTreeByKeywords(List<Record> allRecords, String keywords, String... filterFields) {
- List<Record> listRecord = new ArrayList<Record>();
- Map<String, Record> allRecordMap = new HashMap<String, Record>();
- for (Record record : allRecords) {
- allRecordMap.put(record.getStr("uuid"), record);
- }
- // 遍历allRrecords找出所有的nodeName和关键字keywords相关的数据
- if (allRecords != null && allRecords.size() > 0) {
- if (filterFields.length > 1) {
- for (Record record : allRecords) {
- for (String field : filterFields) {
- // 比较
- if (record.getStr(field).toLowerCase().indexOf(keywords.toLowerCase()) != -1) {
- listRecord.add(record);
- }
- }
- }
- } else {
- for (Record record : allRecords) {
- // 比较
- if (record.getStr(filterFields[0]).toLowerCase().indexOf(keywords.toLowerCase()) != -1) {
- listRecord.add(record);
- }
- }
- }
- }
- // 查找过滤出来的节点和他们的父节点
- listRecord = this.getSelfAndTheirParentRecord(listRecord, new ArrayList<Record>(),
- new HashMap<String, Record>(), allRecordMap);
- // 将过滤出来的数据变成树tree结构
- listRecord = this.useListRecordToTree(listRecord);
- return listRecord;
- }
- /**
- * 说明方法描述:递归查询子节点
- *
- * @param childList 子节点
- * @param parentUuid 父节点id
- * @return
- * @time 2016年5月10日 下午3:29:35
- * @author yangdong
- */
- private List<Record> getTreeChildRecord(List<Record> childList, String parentUuid) {
- List<Record> listParentRecord = new ArrayList<Record>();
- List<Record> listNotParentRecord = new ArrayList<Record>();
- // 遍历tmpList,找出所有的根节点和非根节点
- if (childList != null && childList.size() > 0) {
- for (Record record : childList) {
- // 对比找出父节点
- if (StringUtil.equals(record.getStr("parent_uuid"), parentUuid)) {
- listParentRecord.add(record);
- } else {
- listNotParentRecord.add(record);
- }
- }
- }
- // 查询子节点
- if (listParentRecord.size() > 0) {
- for (Record record : listParentRecord) {
- // 递归查询子节点
- record.set("childs", getTreeChildRecord(listNotParentRecord, record.getStr("uuid")));
- }
- }
- return listParentRecord;
- }
- /**
- * 说明方法描述:递归找出本节点和他们的父节点
- *
- * @param parentList 根据关键字过滤出来的相关节点的父节点
- * @param resultList 返回的过滤出来的节点
- * @param filterRecordMap 已经过滤出来的节点
- * @param allRecordMap 所有节点
- * @return
- * @time 2016年5月19日 上午9:53:56
- * @author yangdong
- */
- private List<Record> getSelfAndTheirParentRecord(List<Record> parentList, List<Record> resultList,
- Map<String, Record> filterRecordMap,
- Map<String, Record> allRecordMap) {
- // 当父节点为null或者节点数量为0时返回结果,退出递归
- if (parentList == null || parentList.size() == 0) {
- return resultList;
- }
- // 重新创建父节点集合
- List<Record> listParentRecord = new ArrayList<Record>();
- // 遍历已经过滤出来的节点
- for (Record record : parentList) {
- String uuid = record.getStr("uuid");
- String parent_uuid = record.getStr("parent_uuid");
- // 如果已经过滤出来的节点不存在则添加到list中
- if (!filterRecordMap.containsKey(uuid)) {
- listParentRecord.add(record);// 添加到父节点中
- filterRecordMap.put(uuid, record);// 添加到已过滤的map中
- allRecordMap.remove(uuid);// 移除集合中相应的元素
- resultList.add(record);// 添加到结果集中
- }
- // 找出本节点的父节点并添加到listParentRecord父节点集合中,并移除集合中相应的元素
- if (StringUtil.isNotBlank(parent_uuid)) {
- Record parentRecord = allRecordMap.get(parent_uuid);
- if (parentRecord != null) {
- listParentRecord.add(parentRecord);
- allRecordMap.remove(parent_uuid);
- }
- }
- }
- // 递归调用
- getSelfAndTheirParentRecord(listParentRecord, resultList, filterRecordMap, allRecordMap);
- return resultList;
- }
- //示例
- /**
- * 说明方法描述:递归查询所有权限
- *
- * @param keyword
- * @param is_deleted
- * @return
- * @time 2016年5月10日 下午3:47:50
- * @author yangdong
- */
- public List<Record> getRecordByKeywordRecursive(String keyword, String is_deleted) {
- // 第一步:查询所有的数据
- StringBuffer sql = new StringBuffer(
- " select pa.uuid,pa.parent_uuid,pa.author_code,pa.author_name,pa.is_menu,pa.sort_number,pa.is_enable,pa.menu_icon ");
- sql.append(" from s_author pa");
- List<Object> params = new ArrayList<Object>();
- sql.append(" where pa.is_deleted=? ");
- params.add(is_deleted);
- sql.append(" order by pa.sort_number asc ");
- List<Record> allRrecords = Db.use(AppConst.DB_DATASOURCE_MAIN).find(sql.toString(), ParamUtil.listToArray(params));
- //第二步:将list变为树tree结构
- if (StringUtil.isNotBlank(keyword)) {
- return super.useListRecordToTreeByKeywords(allRrecords, keyword, "author_name");
- } else {
- return super.useListRecordToTree(allRrecords);
- }
- }
java递归和反向递归的更多相关文章
- 8皇后以及N皇后算法探究,回溯算法的JAVA实现,非递归,循环控制及其优化
上两篇博客 8皇后以及N皇后算法探究,回溯算法的JAVA实现,递归方案 8皇后以及N皇后算法探究,回溯算法的JAVA实现,非递归,数据结构“栈”实现 研究了递归方法实现回溯,解决N皇后问题,下面我们来 ...
- 数据结构二叉树的递归与非递归遍历之java,javascript,php实现可编译(1)java
前一段时间,学习数据结构的各种算法,概念不难理解,只是被C++的指针给弄的犯糊涂,于是用java,web,javascript,分别去实现数据结构的各种算法. 二叉树的遍历,本分享只是以二叉树中的先序 ...
- java.sql.SQLException: ORA-00604: 递归 SQL 级别 1 出现错误
后台报出如下错误: Caused by: java.sql.SQLException: ORA-00604: 递归 SQL 级别 1 出现错误 ORA-01000: 超出打开游标的最大数 ORA-00 ...
- 二叉树3种递归和非递归遍历(Java)
import java.util.Stack; //二叉树3种递归和非递归遍历(Java) public class Traverse { /******************一二进制树的定义*** ...
- Java中函数的递归调用
说到递归,java中的递归和C语言中也是很相似的,在Java中,递归其实就是利用了栈的先进后出的机制来描述的. public class HelloWorld { public static void ...
- Java数据结构和算法 - 递归
三角数字 Q: 什么是三角数字? A: 据说一群在毕达哥拉斯领导下工作的古希腊的数学家,发现了在数学序列1,3,6,10,15,21,……中有一种奇特的联系.这个数列中的第N项是由第N-1项加N得到的 ...
- Java根据子节点递归父节点
先上数据库结构图和树形图: 项目中的一个需求是获取一个商品所属的二级分类名称. 思路分析,首先,我们是可以拿到当前商品所属的子分类的,比如说我买的是一个iPhone SE,对应的分类名称是 iPhon ...
- JAVA递归、非递归遍历二叉树(转)
原文链接: JAVA递归.非递归遍历二叉树 import java.util.Stack; import java.util.HashMap; public class BinTree { priva ...
- java扫描文件夹下面的所有文件(递归与非递归实现)
java中扫描指定文件夹下面的所有文件扫描一个文件夹下面的所有文件,因为文件夹的层数没有限制可能多达几十层几百层,通常会采用两种方式来遍历指定文件夹下面的所有文件.递归方式非递归方式(采用队列或者栈实 ...
随机推荐
- CentOS7使用yum详细搭建zabbix3.2过程
本文引用于:http://blog.csdn.net/s3275492383/article/details/62417210 一.准备搭建环境: 1.系统:CentOS7 2.默认有使用linux服 ...
- Spring/AOP框架, 以及使用注解
1, 使用代理增加日志, 也是基于最原始的办法 import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; ...
- BeanDefinitionStoreException: IOException parsing XML document from ServletContext resource
Tomcat报错如下: BeanDefinitionStoreException: IOException parsing XML document from ServletContext resou ...
- C/C++ 宏
0. #define MALLOC(n, type) \ ( (type *) malloc((n)* sizeof(type))) 1. 宏可以像函数一样被定义,例如: #define min ...
- ios 处理WKContentView的crash
http://www.jianshu.com/p/7ef5814a871b 解决WKContentView没有isSecureTextEntry方法造成的crash 程序中有web页面,使用W ...
- UVa 11988 Broken Keyboard (a.k.a. Beiju Text)(链表)
You're typing a long text with a broken keyboard. Well it's not so badly broken. The only problem wi ...
- collections系列之OrderedDict【有序字典】与DefaultDict【默认字典】
今天来向大家介绍一下collections系列中的OrderedDict和DefaultDict,这两种类均是通过collections来创建的,均是对dict字典加工,所有都继承了dict字典的方法 ...
- PostgreSQL+pgpool-II复制方案
目录 PostgreSQL+pgpool-II复制方案 1. Pgpool-II介绍 2. pgpool-II安装 2.1 安装pgpool-II yum源,并安装pgpool-II 2.2 添加Pg ...
- volatile是否就是原子性/线程同步的
在java线程并发处理中,有一个关键字volatile的使用目前存在很大的混淆,以为使用这个关键字,在进行多线程并发处理的时候就可以万事大吉. Java语言是支持多线程的,为了解决线程并发的问题,在语 ...
- Volley的使用
Volley加载图片到控件上 VolleyUtils.getLoader(getContext()).get(zixun.getPicurl(), ImageLoader.getImageListen ...