上一篇博客介绍到用递归实现树结构数据的查找,那么这篇博客,我就结合本身对于树的理解,而后用一种非递归的方式进行树结构数据的处理。首先,改造数据库表设计,加入度的概念:javascript
首先,layer的设计,是来源于Word文档的目录带来的灵感。想想我本身在写Word文档的时候,经过标题1,标题2等的设立,而后就可能自动生成目录。我感受这个和我要完成的树结构数据的处理有共同之处。固然,在这里的010000,是我本身对于树的度的表示,主要是用于排序,然后面的depth,则是对于我本身方便在Java控制台打印额外添加的一个字段(实际应用,不须要)css
而后是实体类设计:java
<span style="font-family:KaiTi_GB2312;font-size:18px;"> private String id; private String name; private String pid; private String layer; private String depth;</span>
<span style="font-family:KaiTi_GB2312;font-size:18px;"> public List<TreeEntity> findAllData() { <span style="color:#ff0000;">String sql = "select * from test where id is not null order by layer ASC"; </span> List<TreeEntity> treeList = null; try { conn = DbUtil.getConnection(); pstmt = conn.prepareStatement(sql); rs = pstmt.executeQuery(); treeList = new ArrayList<TreeEntity>(); while (rs.next()) { TreeEntity myTree = new TreeEntity(); myTree.setId(rs.getString("id")); myTree.setName(rs.getString("name")); myTree.setPid(rs.getString("pid")); myTree.setDepth(rs.getString("depth")); treeList.add(myTree); } } catch (SQLException e) { e.printStackTrace(); } finally { DbUtil.close(pstmt); DbUtil.close(conn); } return treeList; }</span>
<span style="font-family:KaiTi_GB2312;font-size:18px;">public void displayTree(){ List<TreeEntity> List=this.findAllData(); String prefix=""; for(int i=0; i<List.size(); i++){ if("1".equals(List.get(i).getDepth())){ prefix="|-"; } if("2".equals(List.get(i).getDepth())){ prefix="|----"; } if("3".equals(List.get(i).getDepth())){ prefix="|--------"; } System.out.println(prefix+List.get(i).getName()); } }</span>
首先,这里有几个if语句,是我借助depth字段的值,来进行数据打印的一个过程。通常来讲,做为一个系统的左侧边菜单,度的最大值,应该是在5个左右,少的话,直接在这里写。多的话,则有工厂方法模式能够简单改造。(并且,这一点只是我要在控制台打印出一棵树,本身额外加上的)node
在实际应用中,好比说JQuery的ZTree插件,则有专门对应的简单Array形式的数据加载,以下:
sql
第一种格式加载:标准的带有父子关系的ZTree加载数据库
var zTreeNodes = [ {"id":1, "name":"test1", "nodes":[ {"id":11, "name":"test11", "nodes":[ {"id":111, "name":"test111"} ]}, {"id":12, "name":"test12"} ]}, ...... ];
var treeNodes = [ {"id":1, "pId":0, "name":"test1"}, {"id":11, "pId":1, "name":"test11"}, {"id":12, "pId":1, "name":"test12"}, {"id":111, "pId":11, "name":"test111"}, ...... ];
<span style="font-family:KaiTi_GB2312;font-size:18px;"> public static void main(String[] args) { TreeDepth tree = new TreeDepth(); tree.displayTree(); }</span>
能够看出的是,改造数据库设计以后,只用了1次循环,就实现了最终的效果,而没有用递归。那么问题的关键点有:每次插入数据的时候,layer的值填充问题,那么这个实际上是有规律的,每一个人均可能会有一套本身的填充规律,就好比说个人灵感则来自于Word文档的目录实现。markdown
在用非递归实现了这个树的打印以后,我忽然就明白了以前有一个姑娘问个人问题:她说为何每次左侧边的菜单栏加载的时候,都要从上往下加载,而不是一次性加载完。今天跟了每一步代码以后发现,由于使用递归的时候,就是先把每个结点的孩子结点所有遍历结束后,才会开始加载下一个结点。而使用非递归则不同,由于它是一次性直接加载完全部的数据,因此是一次性加载完毕。数据库设计
对于平时的学习,仍是多总结总结吧。我感受,递归不递归的,其实也不那么重要,根据本身的实际状况进行取舍。函数
循环方法比递归方法快, 由于循环避免了一系列函数调用和返回中所涉及到的参数传递和返回值的额外开销。
学习
递归和循环之间的选择。通常状况下, 当循环方法比较容易找到时, 你应该避免使用递归。