通过一个序列得到一颗树

      假设目前有这样一个序列:ABCDEFG,这个序列中的节点(如:AE)可以是任意实体,而这个序列可能以数组,链表的方式存储。将这个序列转换成如下左图所示的逻辑树,需要哪些条件呢?1.遍历方式为先序(或者其他);2.节点间的关系(如节点的子节点)。即这个序列可以表示为:A(B(C),D,E(F,G))

 

      实际上,条件1完全可以不要:需要遍历方式是要确定根节点(先序)或者叶子节点(后序)。分析可知,没有父亲的节点为根节点(或者没有孩子的节点就是叶子节点)。也就是说,只要有getParent或者getChildren方法,就可以确定各个节点的关系了(节点类型也确定了)。即通过一个序列得到一颗树只需要一个条件:确定节点间关系

确定节点关系两类算法实现:先找到根节点,然后再依次找到子节点直到叶子节点;先确定各个节点的深度,深度最小的(可以设为0)显然就是根节点,依次得到子节点和叶子节点。

      现在假设每个节点都知道自己的孩子节点(即有getChildren方法)。来看看第一种算法如何实现。这里最关键的问题就是如何找到根节点。可以用排除法考虑:某节点的孩子节点一定不是根节点。即遍历所有节点,排除每个节点的孩子节点,最终剩下的就是根节点(可能是多个)。实现如下表所示:

    public List<Object> getRoots(List<Object> list) {

       List<Object> cloneList = new ArrayList<Object>();

       cloneList.addAll(list);

       for(int i=0;i<list.size();i++) {

           Object o = list.get(i);

           //子节点不可能成为根节点,所以移除

           List<Object> children = getChildren(list, o);

           if(children != null && children.size() > 0)

              cloneList.removeAll(children);

       }

       //边界

       if(list.size() == cloneList.size()) {

           return cloneList;

       }else {

           return getRoots(cloneList);

       }

}

      这里要注意,当要排除一个节点时,应该先排除它的孩子节点。要不然,父节点先于孩子节点删除,那么孩子节点就没了父亲而误成了根节点。考虑到时间和空间的问题,并没有使用递归来解决此问题。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值