n-Tree遍历从根节点到所有子节点

时间:2010-10-06 16:49:42

标签: java list tree parent traversal

我有一个List,其中包含数据库中的一些表,其中每行包含一个引用另一行的父字段。喜欢这个

  标题,父母   A,null
  B,A
  C,A
  D,C
  E,B
  F,null

这里A和F是根节点,B和C是A的子节点,D是C的子节点,E依次是B节的子节点。

从此列表中生成树结构的最佳方法是什么?

一种方法是在查找根(没有父母的标题)的列表上进行递归,然后对每个根再次循环遍历列表并附加根节点。然后,对于那些节点,再次遍历完整列表以附加他们自己的任何子节点。

示例:

private Node getNode(SomeData d) {
    List<SomeData> tmp = getChildren(d);
    if (tmp == null OR empty) return new Node(d);

    Node n = new Node(d);
    for (SomeData m : tmp) {
        n.addChild(getNode(m)); // recurse
    }
    return n;
}

private List<SomeData> getChildren(SomeData parent) {
    List<SomeData> tmp = new ArrayList<SomeData>();
    for (SomeData candidateChild : myBigFlatDataList.values()) {
        if (parent.equals(candidateChild)) {
            tmp.add(candidateChild);
        }
    }
    return tmp;
}

有更好的方法吗?

5 个答案:

答案 0 :(得分:1)

由于您从数据库获取数据,因此可以根据属性对行进行排序。然后,每次搜索节点的子节点时,您都​​不需要遍历整个列表。

修改 列表排序后,当您找到所有要查找的子项时,可以停止遍历列表。例如,当您拥有根“A”并开始在此列表中搜索其子项时:

B, A
C, A
E, B  <- when you reach "B" you can assume that there are no
D, C     other nodes which are children of "A" and stop the iteration

答案 1 :(得分:1)

为每个节点重新读取整个文件(或者更糟糕的是查询数据库)是相当昂贵的。我希望你在阅读列表时构建树。这是我的2美分

  1. 让节点成为一组节点(最初为空集)。
  2. 让RootNodes成为所有根节点的集合(最初是空集)。
  3. 对于每对节点(N1,N2):
    1. 对于每个N in(N1,N2),如果N不在节点中,则创建N并插入节点。
    2. 如果N2 == null,还要将N2插入RootNodes(另外您也可以从节点中删除它)
    3. Mark N2.child = N1。
  4. 如果你遵循这个,在迭代结束时你应该有:

    RootNodes = {A,F}
    Nodes = {B,C,D,E}
    
    A.child = B
    A.child = C
    C.child = D
    B.child = E
    

    希望这有帮助。

答案 2 :(得分:1)

您可以一次构建树。您可以对表进行第一次传递以构建所有节点(从名称到节点构建哈希表),然后执行另一个传递,您可以在其中添加两个节点之间的父子关系(将父指针添加到子节点并将子节点添加到父母的孩子名单。)

答案 3 :(得分:1)

这是一个非常好的方式,但它比它必须更天真。

另一条路线只需要线性时间。 SomeData是否有一些唯一标识它的东西?我会这么认为;这可能是SomeData本身正确实现equals()和hashCode()。

让我们说方法int SomeData.getID()。然后我们可以保留我们之前在HashMap中看到的节点。

Map<Integer, Node> visitedNodes = new HashMap...

然后我们只是通过行阅读:

for ( SomeData data : ... ) {
    SomeData parent = data.getParent();
    Node<SomeData> parentNode = getOrCreateNode(parent);
    Node<SomeData> childNode = getOrCreateNode(data);
    parentNode.addChild(childNode);
}

private Node<SomeData> getOrCreateNode(SomeData data) {
    Node<SomeData> node = visitedNodes.get(data.getID());
    if ( node == null ) {
       node = new Node<SomeData>(data);
       visitedNodes.put(data.getID(), node);
    }
    return node;
}

答案 4 :(得分:1)

List<User> list = new ArrayList<User>();
User blankNode;
class User{
    String userid;      
    User child;     
    public User() {
        //blankNode 
    }
    public User(String userid) {
        this.userid = userid; 
    }
    @Override
    public int hashCode(){
        return userid.hashCode();
    }
}
public void addUser(User parent,String userid){
    if(null == userid)return;
    User child = new User(userid);
    parent.child = child;
    list.add(child);        
}
public void removeUser(User child){
    if(null == child)return;        
    list.remove(child);
}
/* move the rank to up - assume
 * secParent - assign to new child
 */
public void boubbleUp(User secParent,  User oldParent, User child){
    if(null == child || null == secParent)return;
    secParent.child = child;
    oldParent.child = null;
}
public List<User> getTopUser(int num){
    if(num <1)return null;
    Map<Integer, List<User>> map = new HashMap<Integer, List<User>>();
    for(User usr : list){
        int count =0;
        User temp = usr.child;
        while(null != temp){
            count++;temp=temp.child;
        }           
        if(map.get(count)== null){
            List<User>  sameNoOfChildren = new ArrayList<User>()    ;
            sameNoOfChildren.add(usr);
            map.put(count, sameNoOfChildren);
        }else{
            map.get(count).add(usr);                
        }
    }
    Integer[] arr = (Integer[]) map.keySet().toArray();
    Arrays.sort(arr);
    List<User> result = new ArrayList<User>();
    for(int i = arr.length-1; i <=arr.length-num; i-- ){
        result.addAll(map.get(i));
    }       
    return result;      
}