如何在n-ary树中查找仅叶子节点

时间:2016-12-25 12:15:09

标签: algorithm tree

我正在尝试解决以下算法:

  

你有一棵n-ary树。找到满足以下条件的所有节点   条件:

     
      
  • 节点具有子节点,但子节点的全部是叶子(它们没有子节点)。返回仅叶子父节点的列表   他们在树上的深度。
  •   

因此,如果我有下面的树,满足上述条件的唯一节点是D,因为它有后代(E),但它们没有子节点。

  I am root!
     /\ \
    A B  F
      /\
     C  D
         \
         E

我正在尝试用Java实现它,但伪代码也适用于我。 我在这里实现了树和节点结构:N-ary trees in Java

我只需要算法。

2 个答案:

答案 0 :(得分:0)

  1. 从根开始
  2. 而左儿子存在:去左儿子
  3. 回到父亲那里检查下一个儿子
  4. 如果没有其他儿子:将父亲插入列表
  5. else将父亲列入名单并转到第2步,但保留深度计数器,如果找到孙子:从列表中删除父亲
  6. 如果完成所有节点:返回列表

    根 / \ \ A B F. / \ C D.   \    ë

  7. 运行示例:

    • 转到A
    • 返回root并将root插入列表
    • 转到B
    • 转到C(因为计数器而从潜在中删除root)
    • 返回B并将B添加到列表
    • 转到D
    • 转到E(由于反击而从潜在中删除B)
    • 返回D并插入列表
    • 回到B
    • 返回root
    • 转到F(不要插入root,因为root已插入[并已删除]
    • 只有D
    • 的返回列表

    为了完成这项工作,您应该为正在检查的节点运行一个计数器(以查看是否存在孙子),并且您应该知道某个节点是否已从列表中删除,因此您不会将其插入再次(我没有明确地写出来,但我使用了2个列表 - 1表示电位,1表示最终)

答案 1 :(得分:0)

好的,我明白了。这是我达成的解决方案。我确信有更好的解决方案 - 欢迎您纠正我。

// kick off the recursion
public Map<Integer, Integer> findLeafOnlyParents(GenericTree<Integer> tree){
        Map<Integer, Integer> resultMap = new HashMap<>();

    // start search from the root
        traverseWithDepth(tree.getRoot(), resultMap, 0);

        return resultMap;
    } 


private void traverseWithDepth(GenericTreeNode<Integer> node,  Map<Integer, Integer> traversalResult, int depth) {

  // check if the current note in the traversal is parent Of leaf-only nodes
  if (isParentOfLeafOnly(node)){
    traversalResult.put(node.data, depth);
  }

  // check the node's children
  for(GenericTreeNode<Integer> child : node.getChildren()) {
    traverseWithDepth(child, traversalResult, depth + 1);
  }

}

// the main logic is here
private boolean isParentOfLeafOnly(GenericTreeNode<Integer> node){
  boolean isParentOfLeafOnly = false;

  // check if the node has children
  if(node.getChildren().size() > 0){

    // check the children of the node - they should not have children
    List<GenericTreeNode<Integer>> children = node.getChildren();
    boolean grandChildrenExist = false; 

    // for each child check if it has children of its own
    for(GenericTreeNode<Integer> child : children) {
      grandChildrenExist = child.getChildren().size() > 0;

      // once found note that the current node has grandchildren,
      // so we don't need to check the rest of the children of the node
      if (grandChildrenExist){
        break;
      }
     }

     // we need only the parents who don't have great children
    isParentOfLeafOnly = !grandChildrenExist;
  }
  return isParentOfLeafOnly;
}