Java技术积累递归调用——解析树的基本实现原理
2015-09-17 17:17
786 查看
在做项目的过程中,经常会用到树结构。关于树结构的框架我也接触过几个,比如easyui中封装的树,Ztree等。当然这些封装好的框架只需要我们去按照API来使用即可,那么树的实现原理究竟是怎样的。今天用最原始的代码来拼接一下树的组成结构。
效果:
id:节点ID,pid;父节点id,level:等级标志(根节点为0,根的一级子节点为1,一次类推),name:节点名称
is_leaf:是否为叶子节点
private StringBuffer sbTreeHTML=new StringBuffer();
可根据注释来理解整个的拼接过程。
接下来,在树结构中,我们需要给他加点击事件,让节点响应点击事件来出现应有的树的结构的效果。在拼接的过程中响应的时间为display(id)
js:
通过以上描述,树结构基本上就已经成型了。剩下的就是在前台页面中调用此方法即可。
分析一下,增删改,只有删除是相对复杂的。它需要考虑的因素比较多,和查询类似,需要考虑是否为叶子节点,如果为非叶子节点,那么就需要进行递归删除它的子节点。还要考虑,删除的节点的父节点下面还有没有其他的子节点,如果没有需要更改父节点为叶子节点。
效果:
1、表结构
要想出现树结构,那么数据库中必须包含有可以形成树结构的表,也就是可以区分出父节点和子节点。id:节点ID,pid;父节点id,level:等级标志(根节点为0,根的一级子节点为1,一次类推),name:节点名称
is_leaf:是否为叶子节点
2、根据树的结构进行拼接
在写这个方法前,首先要创建一个StringBuffer,用来讲这些html拼接成一个完整的字符串。private StringBuffer sbTreeHTML=new StringBuffer();
/** * 递归读取分销商树 * * 第四步,生成树结构 * @param conn * @param id * @param level 控制层次 */ private void readClientTree(Connection conn,int id,int level) throws SQLException{ String sql="select * from t_client where pid=?"; PreparedStatement pstmt=null; ResultSet rs=null; try{ pstmt=conn.prepareStatement(sql); pstmt.setInt(1, id); rs=pstmt.executeQuery(); while(rs.next()){ sbTreeHTML.append("<div>");//每一个节点都作为一个div来出现 sbTreeHTML.append("\n");//另起一行 //遍历树结构的表,根据等级来决定每一个节点前加几个空白。出现缩进的效果。 for(int i=0;i<level;i++){ sbTreeHTML.append("<img src=\"../images/white.gif\">");//空白图片 sbTreeHTML.append("\n"); } //在拼接的时候,要把每个节点的Id和名称读取出来,进行绑定,以便后续操作 if(Constants.No.equals(rs.getString("is_leaf"))){ //如果不是叶子节点的情况,节点前面为一个"+"的图片 sbTreeHTML.append("<img alt=\"展开\" style=\"cursor:hand;\" onClick=\"display('"+rs.getInt("id")+"');\" id=\"img"+rs.getInt("id")+"\" src=\"../images/plus.gif\">"); sbTreeHTML.append("\n"); //“+”图片后面跟着一个关闭标志的***小图片 sbTreeHTML.append("<img id=\"im"+rs.getInt("id")+"\" src=\"../images/closedfold.gif\">"); sbTreeHTML.append("\n"); sbTreeHTML.append("<a href=\"client_node_crud.jsp?id="+rs.getInt("id")+"\" target=\"clientDispAreaFrame\">"+rs.getString("name")+"</a>"); sbTreeHTML.append("\n"); sbTreeHTML.append("<div style=\"display:none;\" id=\"div" + rs.getInt("id") + "\">"); sbTreeHTML.append("\n"); //递归读取子节点 readClientTree(conn,rs.getInt("id"),level+1); sbTreeHTML.append("</div>"); sbTreeHTML.append("\n"); }else{//叶子的情况 sbTreeHTML.append("<img src=\"../images/minus.gif\">");//减号 sbTreeHTML.append("\n"); sbTreeHTML.append("<img src=\"../images/openfold.gif\">");//张开图片 sbTreeHTML.append("\n"); if(Constants.YES.equals(rs.getString("is_client"))){ sbTreeHTML.append("<a href=\"client_crud.jsp?id="+rs.getInt("id")+"\" target=\"clientDispAreaFrame\">"+rs.getString("name")+"</a>"); }else{ sbTreeHTML.append("<a href=\"client_node_crud.jsp?id="+rs.getInt("id")+"\" target=\"clientDispAreaFrame\">"+rs.getString("name")+"</a>"); } } sbTreeHTML.append("\n"); sbTreeHTML.append("</div>");//每个div结束标识 sbTreeHTML.append("\n"); } }finally{ DbUtil.close(rs); DbUtil.close(pstmt); } }
可根据注释来理解整个的拼接过程。
接下来,在树结构中,我们需要给他加点击事件,让节点响应点击事件来出现应有的树的结构的效果。在拼接的过程中响应的时间为display(id)
js:
function display(id) { eval("var div=div"+id); eval("var img=img"+id); eval("var im=im"+id); div.style.display=div.style.display=="block"?"none":"block"; img.src=div.style.display=="block"?"../images/minus.gif":"../images/plus.gif"; im.src=div.style.display=="block"?"../images/openfold.gif":"../images/closedfold.gif"; img.alt=div.style.display=="block"?"展开":"关闭"; }
通过以上描述,树结构基本上就已经成型了。剩下的就是在前台页面中调用此方法即可。
三、删除节点
接下来就是对树的操作了。分析一下,增删改,只有删除是相对复杂的。它需要考虑的因素比较多,和查询类似,需要考虑是否为叶子节点,如果为非叶子节点,那么就需要进行递归删除它的子节点。还要考虑,删除的节点的父节点下面还有没有其他的子节点,如果没有需要更改父节点为叶子节点。
/** * 递归删除 * @param conn */ public void recursionDelNode(Connection conn,int id) throws SQLException{ String sql="select * from t_client where pid=?"; PreparedStatement pstmt=null; ResultSet rs=null; try{ pstmt=conn.prepareStatement(sql); pstmt.setInt(1, id); rs=pstmt.executeQuery(); while(rs.next()){ //判断如果为非叶子节点,进行递归查询 if(Constants.No.equals(rs.getString("is_leaf"))){ recursionDelNode(conn,rs.getInt("id")); } //执行删除操作 delNode(conn,rs.getInt("id")); } //删除自身节点 delNode(conn,id); }catch(SQLException e){ e.printStackTrace(); }finally{ DbUtil.close(rs); DbUtil.close(pstmt); } } /** * 删除节点 * @param conn * @param id */ public void delNode(Connection conn,int id) throws SQLException{ String sql="delete from t_client where id=?"; PreparedStatement pstmt=null; try{ pstmt=conn.prepareStatement(sql); pstmt.setInt(1, id); pstmt.executeUpdate(); }catch(SQLException e){ e.printStackTrace(); }finally{ DbUtil.close(pstmt); } }以上就是整个关于拼接树结构的核心部分了。树是Web端常用的界面效果,利用它在很多方面可以清晰的表达组织结构,给大家一目了然的效果,了解它的原理以应万变!
相关文章推荐
- eclipse快捷键大全
- Java代码编码规范(1)
- java学习笔记之内部类
- Java的native关键字---JAVA下调用其他语言的关键词
- mac上java的真正位置
- 单词串最后单词的长度
- Gradle在大型Java项目上的应用
- ubuntu eclipse 集成pyDev
- Struts2 笔记第一天
- Java中使用hex string类型的RSA密钥加解密测试
- java.lang.OutOfMemoryError: PermGen space 解决方法
- java语言基础之面向对象1
- 学习日志---查找算法
- JDK 1.8 新特性
- JDK 1.7 新特性
- JDK 1.6 新特性
- (MyEclipse) MyEclipse完美破解方法(图)
- 【Spring】Spring MVC Controller 参数中文乱码
- Java8改进的HashMap和Hashtable实现类
- Java实现的堆排序(最小堆)