(id,pid)格式数据转树和森林结构工具类设计与实现

本文介绍了如何将(id, pid)格式的数据转换为树形和森林结构,适用于构建多级权限树、分类等场景。通过设计自定义节点类和森林管理类,实现从(id, pid)到(id, children)的转化,优化了大量层级查询的性能问题,适合一次性加载全树的情况。" 45846761,4992911,使用结构体创建电话通讯录,"['C语言', '数据结构', '文件操作']

树形结构很多地方都有应用,比如我们在构造网站后台的授权限树的时候,再比如我们在设计多级留言的时候、还有分类等等。

有些时候我们的树形结构并不需要过多设计,这是因为我们的很多时候对这棵树的要求不高(两层、三层就行了),这时候我们很容易的会按照层级划分树形结构,然后查询数据库的时候会一层一层的嵌套查询。如果层次比较浅这种做法是可取的(或者我们本来就不打算一次将树加载完全,而是在需要时再加载,那分层级的多次加载也许有用武之地)。但是考虑这种情况:我们的树比较深,而且要一次加载完全。要是按照一层一层的加载原则,那么光是访问数据库的查询语句就是指数形式的了。性能肯定不好。那么除了一层一层的查询好有更好的办法吗?肯定是有的,多查询一些资料会发现这种做法比较常见了:(id,pid),通俗说就是一个节点只需要记住自己的id和父亲的id(根节点没有pid可以设置一个特殊值)就可以拥有呈现这棵树的完整结构全部信息了,仔细想一想自己学过的数据结构,是不是这样的?好了这样一来我们在设计数据库的时候就可以很轻松的设计一棵树的树形结构了。那么有个问题,我们在展现出来的时候总不能直接显示一连串的(id,pid)集合吧。我们要的是树形结构。这时候我们其实非常想实现的是从(id,pid)到

(id,children【】)的转化。毕竟我们在展现树形结构的时候后一种格式更适合页面的呈现,而前一种比较适合数据的存储格式。

好了废话不多说了,下面是代码示例:

首先是自定义节点类:

/**
 * 节点类
 * @author bearsmall
 *
 */
public class TreeNode {
	private int id;//主键ID
	private int pid;//父节点ID
	private Object content;//节点内容
	private List<TreeNode> children = new ArrayList<TreeNode>();//子孙节点
	
	public TreeNode(int id, Object content) {
		this.id = id;
		this.content = content;
	}
	public TreeNode(int id, int pid, Object content) {
		this.id = id;
		this.pid = pid;
		this.content = content;
	}
	
	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	public int getPid() {
		return pid;
	}
	public void setPid(int pid) {
		this.pid = pid;
	}
	public Object getContent() {
		return content;
	}
	public void setContent(Object content) {
		this.content = content;
	}
	public List<TreeNode> getChildren() {
		return children;
	}
	public void setChildren(List<TreeNode> children) {
		this.children = children;
	}
	@Override
	public String toString() {
		return "TreeNode [id=" + id + ", pid=" + pid + ", content=" + content
				+ ", children=" + children + "]";
	}
}

然后是树节点管理类:

/**
 * 树节点管理类
 * 
 * @author
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值