一、基本概况

上一篇博客介绍到用递归实现树结构数据的查找,那么这篇博客,我就结合自己对于树的理解,然后用一种非递归的方式进行树结构数据的处理。首先,改造数据库表设计,加入度的概念:

首先,layer的设计,是来源于Word文档的目录带来的灵感。想一想我自己在写Word文档的时候,通过标题1,标题2等的设立,然后就可能自动生成目录。我感觉这个和我要完成的树结构数据的处理有共同之处。当然,在这里的010000,是我自己对于树的度的表示,主要是用于排序,而后面的depth,则是对于我自己方便在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>

建立实体类的get和set方法

二、代码实现

1,查询所有的数据

<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>

事实上,执行了这个方法之后,数据库的数据,就已经是按照菜单形式排列整齐的数据了。那么,怎么显示的更为美观呢?

2,显示树

<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个左右,少的话,直接在这里写。多的话,则有工厂方法模式可以简单改造。(而且,这一点只是我要在控制台打印出一棵树,自己额外加上的)

在实际应用中,比如说JQuery的ZTree插件,则有专门对应的简单Array形式的数据加载,如下:

第一种格式加载:标准的带有父子关系的ZTree加载

var zTreeNodes = [
{"id":1, "name":"test1", "nodes":[
{"id":11, "name":"test11", "nodes":[
{"id":111, "name":"test111"}
]},
{"id":12, "name":"test12"}
]},
......
];

第二种格式加载:带有父子关系的简单Array格式加载

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"},
......
];

在实际应用的时候,完全可以采用第二种数据加载方式,让程序变得更为简单!

3,主程序代码及结果

<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文档的目录实现。

在用非递归实现了这个树的打印之后,我突然就明白了之前有一个姑娘问我的问题:她说为什么每次左侧边的菜单栏加载的时候,都要从上往下加载,而不是一次性加载完。今天跟了每一步代码之后发现,因为使用递归的时候,就是先把每一个结点的孩子结点全部遍历结束后,才会开始加载下一个结点。而使用非递归则不一样,因为它是一次性直接加载完所有的数据,所以是一次性加载完毕。

四、总结

对于平时的学习,还是多总结总结吧。我感觉,递归不递归的,其实也不那么重要,根据自己的实际情况进行取舍。

循环方法比递归方法快, 因为循环避免了一系列函数调用和返回中所涉及到的参数传递和返回值的额外开销。

递归和循环之间的选择。一般情况下, 当循环方法比较容易找到时, 你应该避免使用递归。

【java基础 4】树形结构数据呈现的非递归算法(循环)实现的更多相关文章

  1. 【Tree 2】树形结构数据呈现的非递归算法(循环)实现

    一.基本概况 上一篇博客介绍到用递归实现树结构数据的查找,那么这篇博客,我就结合自己对于树的理解,然后用一种非递归的方式进行树结构数据的处理.首先,改造数据库表设计,加入度的概念: 首先,layer的 ...

  2. java基础-迭代器(Iterator)与增强for循环

    java基础-迭代器(Iterator)与增强for循环 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.Iterator迭代器概述 Java中提供了很多个集合,它们在存储元素时 ...

  3. 【java基础 3】树形结构数据呈现的递归算法实现

    一.基本概况 在我的项目中,常常会用到树形结构的数据,最为明显的就是左边菜单栏,类似于window folder一样的东西. 而我之前一直是借助前端封装好的ZTree等工具实现展示,而后台则通常使用递 ...

  4. 【Tree 1】树形结构数据呈现的递归算法实现

    一.基本概况 在我的项目中,常常会用到树形结构的数据,最为明显的就是左边菜单栏,类似于window folder一样的东西. 而我之前一直是借助前端封装好的ZTree等工具实现展示,而后台则通常使用递 ...

  5. Java基础:执行时异常和非执行时异常

    1.Java异常机制 Java把异常当做对象来处理,并定义一个基类java.lang.Throwable作为全部异常的超类. Java中的异常分为两大类:错误Error和异常Exception.Jav ...

  6. 黑马程序员——JAVA基础之JDK1.5新特性高级for循环和可变参数

    ------- android培训.java培训.期待与您交流! ---------- 高级for循环   格式: for(数据类型 变量名 : 被遍历的集合(Collection)或者数组) {   ...

  7. Java基础—控制流程语句(条件语句与循环结构)

    与任何程序设计语言一样,Java使用条件语句和循环结构确定控制流程.Java的控制流程结构与C和C++的控制流程机构一样,只有很少的例外情况.没有goto语句,但break语句可以带标签,可以利用它实 ...

  8. 【java基础 5】树形结构数据加载的思考

    前面两篇文章,分别介绍了使用递归和非递归算法加载树形结构数据的方式,本篇文章,则是自己闲下来的时候,进行的一点小思考. 一.什么地方会用到树形结构 刚开始一看到这种结构的时候,最先是想到了家谱.家谱就 ...

  9. Java基础-SSM之mybatis的树形控件(自关联)

    Java基础-SSM之mybatis的树形控件(自关联) 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.准备测试环境(创建数据库表) 1>.创建areas表: use y ...

随机推荐

  1. 18.5.1使用Proxy和InvocationHandler创建动态代理

    package d18_5_1; public interface Person { void walk(); void sayHello(String name); } package d18_5_ ...

  2. Centos 6.5安装MySQL-python

    报错信息: Using cached MySQL-python-1.2.5.zip     Complete output from command python setup.py egg_info: ...

  3. props.children 和容器类组件

    有一类组件,充当了容器的作用,它定义了一种外层结构形式,然后你可以往里面塞任意的内容.这种结构在实际当中非常常见,例如这种带卡片组件: 组件本身是一个不带任何内容的方形的容器,我可以在用这个组件的时候 ...

  4. P1116 车厢重组

    题目描述 在一个旧式的火车站旁边有一座桥,其桥面可以绕河中心的桥墩水平旋转.一个车站的职工发现桥的长度最多能容纳两节车厢,如果将桥旋转180度,则可以把相邻两节车厢的位置交换,用这种方法可以重新排列车 ...

  5. 使用预定义的action值启动系统应用

    1.启动浏览器 Intent intent = new Intent(); intent.setAction(Intent.ACTION_WEB_SEARCH); //可以传一个搜索关键字,会直接显示 ...

  6. (4)《Head First HTML与CSS》学习笔记---文本的CSS规则和盒模型;div与span;<a>元素的链接色;伪类

    1.每个font-family包含一组共同特征的字体.共五个字体系列: sans-serif----这个系列包括了没有衬线的字体,与serif相比,通常认为这个系列更容易在计算机上识读. serif- ...

  7. 新建cordova应用

    使用命令行(本例命令行均使用as或webstrom的命令行),在任意目录输入以下命令新建cordova应用 cordova create capp1 com.cesc.ewater.capp1 其中c ...

  8. Android开发二维码之坑

    之前一直做的是.NET开发用的是C#语言,近段时间由于做一个APP这才用上了java,在二维码扫描整合到APP里面遇到扫描二维码之后没有返回值,经过反复的尝试最后终于拿到了返回值,之后觉得很有必要记录 ...

  9. Oracle的数据伪列(ROWNUM)

    作者:Vashon 时间:20150414 数据库:Oracle11g 数据伪列(ROWNUM) *范例:查询前5条记录:select rownum,empno,job,hiredate,sal fr ...

  10. 原创:E325: ATTENTION vim超完整超给力的问题与解决方法

    又到了老葵花哥哥开课的时间 这是给大家提供一个企业常见的错误 我相信大家生活还编程中会长期使用接触这个错误 这里我们经常用的两个选项 (E)dit any way 编辑原来的文件,忽略刚刚做的修改 ( ...