`
gege_s
  • 浏览: 18156 次
  • 性别: Icon_minigender_1
  • 来自: 郑州
社区版块
存档分类
最新评论

树形结构之二 运用递归加载你想要的结构

阅读更多

接着上面的一往篇,继续说树型结构的事。

 

上面一篇提到如何建立一个业务无关的结点,下面就要说一下树的组装。

 

设计思想是调用者通过TreeBuilder的构造方法加载所有结点,根据不同的需求通过TreeBuilder提供的方法得到相应的信息。

待树型结构被装配完成,通过拿到一个根结点就可以拿出整棵树的信息。

 

一点一点来吧:

 

--------------------------------------------

 

public class TreeBuilder<T> {
	private static Logger logger = Logger.getLogger(TreeBuilder.class);
	protected boolean inited=false;		//是否已经初始化
	private List<Node<T>> nodes;		//根结点以外的结点
	private Node<T> root;				//根结点
	public TreeBuilder(Node<T> root,List<Node<T>> nodes){
		if (root == null) {
			throw new RuntimeException("未指定根结点!");
		}
		if (nodes == null || nodes.size() == 0) {
			throw new RuntimeException("没有叶子结点不能生成树!");;
		}
		this.root=root;
		this.nodes=nodes;
	}
}

 

 从以上代码中可以得到以下信息:

1.它是一个泛型类,类型与结点的扩展属性的类型保持一致。

2.它要求一次性加载所有结点。

 

下面是一重要方法:

1.装配树型结构:

 

 

/**
	 * 装配树
	 * @param node
	 * @param grade		结点级别
	 * @param setParent 是否设置父结点,有时候没有必要设置,这样可以减少流量
	 */
	protected void setupTree(Node<T> node, int grade,boolean setParent) {
		
		for (Node<T> n : nodes) {
			if (n.getParentId().equals(node.getId())) {
				n.setGrade(grade);
				node.addChild(n);
				if (n.getParentId().equals(root.getId())) {
					n.setIsexpand(true);
				}
				setupTree(n, grade + 1,setParent);//递归装配所有结点,这里有个不妥,未进行循环引用检测
			}
			if(setParent){
				n.setParent(node);
			}
		}
	}

 

2.对结点进行排序

 

 

/**
	 * 对结点进行排序
	 * @param node
	 */
	public void sort(Node<T> node){
		if (node==null) {
			return;
		}
		if(node.getChildren()!=null&&node.getChildren().size()>0){
			for (Node<T> n:node.getChildren()) {
				sort(n);
			}
			Collections.sort(node.getChildren());
		}
	}

 

3.实用方法-得到经过排序的根结点

 

 

/**
	 * 得到根结点 
	 * @return
	 */
	public Node<T> getRoot() {
		if (!inited) {
			init(false);
		}
		sort(root);
		return root;
	}
 

4. 设置所有结点包含结点的最大深度

 

 

/**
	 * 设置各个结点下面包含结点的最深层次
	 * @throws Exception
	 */
	protected void setupSubLevelsNum() throws Exception {
		if (!inited) {
			init(false);
		}
		if(nodes==null)
			return;
		for (Node<T> n : getLeaves()) {
			int i=1;
			while(n.getParent()!=null){
				Node<T> parent=n.getParent();
				if(parent.getSubLevels()<i)
					parent.setSubLevels(i++);
				n=parent;
			}
			
		}
		root.setSubLevels(getMaxLevel());	
	}
 

5. 得到已经设置好最深层次的树的根结点

 

 

public Node<T> getKnowSubLevelsRoot() throws Exception {
		setupSubLevelsNum();
		return root;
	}
 

6.得到树的深度

 

 

/**
	 * 得到树的最大深度
	 * @return
	 */
	public int getMaxLevel() {
		if (nodes==null||nodes.size()==1) {
			return 1;
		}
		int level=1;
		for(Node<T> node:getLeaves()){
			if (node.getGrade()>level) {
				level=node.getGrade();
			}
		}
		return level;
	}

 

7.提到指定结点的所有子结点

 

public List<Node<T>> getChildrenInNodeId(String id) {
		for (Node<T> n : nodes) {
			if (n.getId().equals(id)) {
				return n.getChildren();
			}
		}
		return null;
	}

 

8.得到指定级别的所有结点

 

 

public List<Node<T>> getNodesInGraged(int grage) throws Exception {
		if (!inited) {
			init(false);
		}
		List<Node<T>> list = new ArrayList<Node<T>>();
		for (Node<T> n : nodes) {
			if (n.getGrade() == grage) {
				list.add(n);
			}
		}
		return list;
	}

 

9.得到所有叶子结点

 

 

public List<Node<T>> getLeaves() {
		List<Node<T>> list = new ArrayList<Node<T>>();
		for (Node<T> n : nodes) {
			if (n.getChildren() == null) {
				list.add(n);
			}
		}
		return list;
	}

 

 

到此树的常用功能已经整合好了,只要去实例化一个treebuilder就可以做得到一个树型结构了。

 

在下一篇,我会说一些如何在前台展示树型结构的内容,希望大家来捧场。

谢谢大家!!

欢迎留言!

 

 

--------------------------------------------

分享到:
评论

相关推荐

    JAVA上百实例源码以及开源项目

    1个目标文件,JNDI的使用例子,有源代码,可以下载参考,JNDI的使用,初始化Context,它是连接JNDI树的起始点,查找你要的对象,打印找到的对象,关闭Context…… ftp文件传输 2个目标文件,FTP的目标是:(1)提高...

    JAVA上百实例源码以及开源项目源代码

    1个目标文件,JNDI的使用例子,有源代码,可以下载参考,JNDI的使用,初始化Context,它是连接JNDI树的起始点,查找你要的对象,打印找到的对象,关闭Context…… ftp文件传输 2个目标文件,FTP的目标是:(1)提高...

    java源码包---java 源码 大量 实例

    1个目标文件,JNDI的使用例子,有源代码,可以下载参考,JNDI的使用,初始化Context,它是连接JNDI树的起始点,查找你要的对象,打印找到的对象,关闭Context…… ftp文件传输 2个目标文件,FTP的目标是:(1)提高...

    java源码包2

    1个目标文件,JNDI的使用例子,有源代码,可以下载参考,JNDI的使用,初始化Context,它是连接JNDI树的起始点,查找你要的对象,打印找到的对象,关闭Context…… ftp文件传输 2个目标文件,FTP的目标是:(1)提高...

    java源码包3

    1个目标文件,JNDI的使用例子,有源代码,可以下载参考,JNDI的使用,初始化Context,它是连接JNDI树的起始点,查找你要的对象,打印找到的对象,关闭Context…… ftp文件传输 2个目标文件,FTP的目标是:(1)提高...

    java源码包4

    1个目标文件,JNDI的使用例子,有源代码,可以下载参考,JNDI的使用,初始化Context,它是连接JNDI树的起始点,查找你要的对象,打印找到的对象,关闭Context…… ftp文件传输 2个目标文件,FTP的目标是:(1)提高...

    成百上千个Java 源码DEMO 4(1-4是独立压缩包)

    EJB中JNDI的使用源码例子 1个目标文件,JNDI的使用例子,有源代码,可以下载参考,JNDI的使用,初始化Context,它是连接JNDI树的起始点,查找你要的对象,打印找到的对象,关闭Context…… ftp文件传输 2个目标文件...

    成百上千个Java 源码DEMO 3(1-4是独立压缩包)

    EJB中JNDI的使用源码例子 1个目标文件,JNDI的使用例子,有源代码,可以下载参考,JNDI的使用,初始化Context,它是连接JNDI树的起始点,查找你要的对象,打印找到的对象,关闭Context…… ftp文件传输 2个目标文件...

    C#编程经验技巧宝典

    27 &lt;br&gt;0056 强行改变运算符的运算顺序 27 &lt;br&gt;第3章 程序算法 29 &lt;br&gt;3.1 数据结构 30 &lt;br&gt;0057 如何实现单向链表 30 &lt;br&gt;0058 如何实现双向链表 35 &lt;br&gt;0059 如何实现堆栈 41 ...

Global site tag (gtag.js) - Google Analytics