在Java树中查找子项(递归)

时间:2016-05-24 13:28:40

标签: java recursion tree

感谢您查看。我想要的是获取树,其中root id是param传递的id,但它返回的空指针。

树设置

TreeIF<DoctorIF> tree = new Tree<DoctorIF>();

   setTree(tree);

   DoctorS ceo = new DoctorS(1, this);
   DoctorS two = new DoctorS(2, this);
   DoctorS three = new DoctorS(3, this);
   DoctorS four = new DoctorS(4, this);
   DoctorS five = new DoctorS(5, this);
   DoctorS six = new DoctorS(6, this);
   DoctorS seven = new DoctorS(7, this);

   TreeIF<DoctorIF> t1 = new Tree<DoctorIF>(three);
   TreeIF<DoctorIF> t2 = new Tree<DoctorIF>(four);
   TreeIF<DoctorIF> t3 = new Tree<DoctorIF>(two);
   tree.setRoot(ceo);

   t1.addChild(new Tree<DoctorIF>(seven));
   t2.addChild(new Tree<DoctorIF>(five));
   t3.addChild(t1);
   t3.addChild(t2);
   t3.addChild(new Tree<DoctorIF>(six));

   tree.addChild(t3);

获取树或树儿童的功能。当我在搜索id {4,5,6,7}时,我得到了nullpointer。

private TreeIF<DoctorIF> getTreeChild(TreeIF<DoctorIF> tree_, int id){
    if (tree_.getRoot().getId()==id && id!=1)return tree_;
    else{
        ListIF<TreeIF<DoctorIF>> list = tree_.getChildren();
        IteratorIF<TreeIF<DoctorIF>> it = list.getIterator();
        while(it.hasNext()){
            TreeIF<DoctorIF> subtree = getTreeChild(it.getNext(), id);
            if (subtree.getRoot()!=null && subtree.getRoot().getId()==id)return subtree;
        }
    }
    return null;
}

 @Override
public DoctorIF getDoctor(int id){
    TreeIF<DoctorIF> tree_ = null;
    tree_ = getTreeChild(tree, id);
    return tree_.getRoot();
}

2 个答案:

答案 0 :(得分:1)

我添加了一些评论来解释我的更改:

private TreeIF<DoctorIF> getTreeChild(TreeIF<DoctorIF> tree_, int id){
    if (tree_.getRoot().getId()==id && id!=1)return tree_;
    else{
        ListIF<TreeIF<DoctorIF>> list = tree_.getChildren();
        IteratorIF<TreeIF<DoctorIF>> it = list.getIterator();
        while(it.hasNext()){
            TreeIF<DoctorIF> subtree = getTreeChild(it.getNext(), id);
            //subtree might be null at this point
            //In that case, subtree.getRoot() will throw a NullPointerException
            if (subtree == null) continue; //This will prevent the NullPointerException
            if (subtree.getRoot()!=null && subtree.getRoot().getId()==id)return subtree;
        }
    }
    return null;
}

答案 1 :(得分:1)

你的功能不必要地复杂。如果找到了子树,则返回子树,否则返回null。所以你不必两次检查id。

getTreeChild可以返回null,但是您可以在不进行检查的情况下取消引用它,因此可能是空指针异常的来源。

这应该有效:

private TreeIF<DoctorIF> getTreeChild(TreeIF<DoctorIF> tree_, int id){
    if (tree_.getRoot().getId()==id && id!=1)return tree_;
    else{
        ListIF<TreeIF<DoctorIF>> list = tree_.getChildren();
        IteratorIF<TreeIF<DoctorIF>> it = list.getIterator();
        while(it.hasNext()){
            TreeIF<DoctorIF> subtree = getTreeChild(it.getNext(), id);
            if (subtree != null) return subtree; // No need to check the id again.
        }
    }
    return null;
}

你的代码看起来有点混乱,像这样的Iterator。如果您拥有ListIF工具Iterable<...>并且IteratorIF实施Iterator<...>,则可以使用java for-each循环。

// ListIF<TreeIF<DoctorIF>> list = tree_.getChildren();
// IteratorIF<TreeIF<DoctorIF>> it = list.getIterator();
// while(it.hasNext()){
//     TreeIF<DoctorIF> subtree = getTreeChild(it.getNext(), id);
//     if (subtree != null) return subtree;
// }

for(TreeIF<DoctorIF> child : tree_.getChildren()) {
    TreeIF<DoctorIF> subtree = getTreeChild(child, id);
    if (subtree != null) return subtree; 
}