java 树 数据结构_基于java的树形数据结构实现

该博客介绍了一个基于Java的树形数据结构实现,用于快速查询文件目录。树节点存储在HashMap中,通过特定方法可以构建有序树。博客详细讨论了效率、先根遍历等操作,并提供了文件目录树的实现。
摘要由CSDN通过智能技术生成

需要实现一个文件目录树,用于文件的快速查询,因此打算实现一个快速的树形结构。

设计思路是所有树节点均存储在map中,根中保留有子节点的key的Set字段child。因此树也可以根据需要改造成为有序树,可以修改childInit或使用构造器Forest(Supplier extends Set> childInit)即可将默认的HashSet修改为TreeSet。完成有序树。 获得以某节点作为根的树形结构

27f09284480d0620f2656325a40de5b3.png

效率:

因为节点均存储在hashmap中,在1.8的haspMap实现中,主要是依据hash+红黑树,因此构建节点数m,时间复杂度为mlog(m) 构建|移动|删除 时间复杂度为2NO(log(n)),n=节点数,appendChain(ks.length=2); 获取某节点O(log(n)) n=总节点个数.

先根遍历在不考虑栈的情况下,某树下的所有节点 nO(nlog(n)) n=子树节点数

注:

key 的判断主要是需要满足hashmap 对key 的要求,即为hashcode和equals。因此重写这两个方法即可.

首先实现一个基础的树形数据结构。

/**

*

* @author yuyi

* @param

*/

public class Forest implements Serializable, Cloneable {

private static final long serialVersionUID = 1L;

protected Supplier extends Set> childInit = () -> new HashSet<>();

private Set roots = childInit.get();

protected HashMap map;

public Tree get(K key) {

return map.get(key);

}

/** 独立某个子树 */

public Tree aloneTree(K k1) {

Tree t = get(k1);

if (t == null)

return null;

if (t.par != null) {

t.parent().child.remove(k1);

t.par = null;

roots.add(k1);

}

return t;

}

/**

* 添加一个有序链

*

*

 
 

* 例如添加 1 2 3 则树为{k=1,son=[{k=2,son=[{key=3}]}]}

* 再次添加 1 4 则树为{k=1,son=[{k=2,son=[{key=3}]},{key=4}]}

* 再次添加 2 4 则树为{k=1,son=[{k=2,son=[{key=3},{key=4}]}]}

*

*

* @param ks

* 线性有序子树(即每层仅一个节点)

* @return

*/

@SuppressWarnings("unchecked")

public Forest appendChain(K... ks) {

assert ks != null && ks.length > 2 && ks[0] != null && ks[1] != null;

K k, pk = null;

int i = 0;

Tree curr = map.get(ks[i]), par = curr != null ? curr.parent() : null;

Set f = roots;

if (par != null) {

i = 1;

f = par.child;

}

for (; ks.length > i; i++) {

if (Objects.equals(k = ks[i], pk))

continue;

if ((curr = map.get(pk = k)) == null) {

curr = new Tree(k);

}

if (!f.contains(k)) {

if (par == null || !Objects.equals(curr.par, par)) {

if (curr.par == null)

roots.remove(k);

else

curr.parent().child.remove(k);

curr.par = par != null ? par.key : curr.par;

f.add(k);

map.put(k, curr);

}

}

par = curr;

f = curr.child;

}

return this;

}

public Forest appendChain(Iterator iterator) {

assert iterator != null;

Set f = roots;

Tree curr = null, par = null;

K k, pk = null;

while (iterator.hasNext()) {

if (Objects.equals(k = iterator.next(), pk))

continue;

if ((curr = map.get(k)) == null) {

curr = new Tree(k);

}

if (!f.contains(k)) {

if (par == null || !Objects.equals(curr.par, par)) {

if (curr.par == null)

roots.remove(k);

else

curr.parent().child.remove(k);

curr.par = par != null ? par.key : curr.par;

if (curr.par != null && roots == f) {

f = curr.parent().child;

}

f.add(k);

map.put(k, curr);

}

}

par = curr;

f = curr.child;

}

return this;

}

public void setRoots(Collection trees) {

trees.iterator()

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值