【问题标题】:C++ getting lowest level of a treeC ++获得树的最低级别
【发布时间】:2021-12-23 05:27:32
【问题描述】:

我需要知道一棵树有多少叶子,但有一些条件。

  • 所有的孩子或叶子,总是在同一个级别,但它可以是级别 1,2,3,4,5 ...我不知道会是哪一个。所以你不能计算孙子+孙子...他们将处于同一级别并且将是他们中较低的,在这种情况下:孙子。
  • 必须有一个没有叶子的节点,但如果它不是最底层的叶子,则不必算叶子。

我会尝试用一些例子来解释自己。想象一下你有这棵树:

 A
 |- B
 |  |- B1
 |  |- B2                 Number of 'leafs' = 2 (B1 and B2). C doesn't count as it is in an 
 |                                                           upper level)
 |- C

另一个例子:

 A
 |- B
 |  |- B1
 |  |- B2                 Number of 'leafs' = 3 (B1,B2,D1)
 |
 |- C
 |- D
    |-D1

另一个例子:

 A
 |- B
 |  |- B1
 |  |   |-B11
 |  |- B2                 Number of 'leafs' = 1 (B11). D1 is not a leaf. It is a 'node' as 
 |                                    leafs in this case are in level 4 (counting A as 1)
 |- C
 |- D
    |-D1

我正在使用类似于 QTreeWidgetItem 的 C++ 和 Qt,所以我有一个对象(我们称它为 myTree,我可以问类似:myTree->childCount() 所以在第一个示例中,如果我调用它,它会说2(B和C),每一个我都可以重复操作。

我试图计算所有给我 childcount() 的东西,但是它给了我 4(B、C、B1 和 B2)而不是 2(B1、B2),这就是我想要的......我把我在尝试什么:

 int grandchild = 0;
   for (int i = 0; i < myTree->childCount( ); ++i)
   {
        Obj* child = myTree->child( i ); //Get the children. First time will be B and C
        if (child)
        {
          grandchild += p_child->childCount( ); // Here I wanted to get a total, for first example, I will get 3 which is not what I want 
        }
    }

提前谢谢你。

【问题讨论】:

  • 您希望每个节点报告其子节点中最远的叶子距离以及该距离处的叶子数量。递归调用它以获得您的答案。你有什么问题?
  • 如果你要接近“孙子”,那你已经走得太远了。
  • @JohnFilleau '报告最远的叶子距离,' 哦..我没想到那个选项!谢谢!关于递归,需要检查怎么做:)为什么你认为孙子太远了?它可能是一棵有 10 层的树......(希望不是呵呵)
  • 在处理递归算法时,递归的当前迭代应该只关心它自己,以及它“下面”的东西。给定节点上的这个操作应该只使用相同的操作检查它的子节点,并返回结果。它应该只关心它的孩子。如果一个节点开始关心它的孙子节点,那么你就是在让自己变得更加困难。
  • 可能是因为不需要跟踪三个级别的节点。仅跟踪父项和子项即可轻松计算树高。例如,二叉树的递归树高度类似于int get_height(Node * current) { if (!current)return 0; return 1+ max(get_height(current-&gt;right), get_height(current-&gt;left)); 对于非二叉树,您可以扩展以获得任意数量的子树的最大值,并且您必须为自己的额外特殊规则添加逻辑。

标签: c++ algorithm qt tree qtreewidget


【解决方案1】:

对于递归函数,您首先假设函数在节点上运行时将返回有关该节点的所有相关信息。然后每个节点只需要检查它的子节点和它自己来决定返回它上面的级别。

如果该节点没有子节点,则结果很简单:该节点在深度为 0(自身)处有一个最大深度节点。

否则,最大深度等于其子级中最大的最大深度+1,并且计数等于共享最大最大深度的所有子级的计数之和。

#include <utility>
#include <vector>

struct node_type {
    std::vector<node_type*> children;
};

// returns the max depth between the node and all of its children
// along with the number of nodes at that depth
std::pair<int, int> max_depth_count(const node_type& node) {
    int depth = 0; // itself
    int count = 1; // itself

    for (const auto c : node.children) {
        auto [child_depth, child_count] = max_depth_count(*c);
        child_depth++;

        if (child_depth > depth) {
            depth = child_depth;
            count = child_count;
        }
        else if (child_depth == depth) {
            count += child_count;
        }
    }

    return {depth, count};
}

【讨论】:

    【解决方案2】:

    一种方法是执行广度优先遍历。这样你一个接一个地访问,最后一个非空级别的大小就是你所需要的。

    这样的广度优先遍历可以使用队列来完成。

    您可以使用问题中提供的接口(@98​​7654321@、childCountchild)对其进行编码:

    int n = 0; // number of nodes in the "current" level
    if (myTree != nullptr) {
        std::queue<Obj*> q;
        q.push(myTree); // The first level just has the root
        while (q.size()) { // While the level is not empty...
            n = q.size(); // ...remember its size
            for (int i = 0; i < n; ++i) { // ...and replace this level with the next
                Obj* node = q.front();
                q.pop();
                int m = node->childCount();
                for (int j = 0; j < m; ++j) {
                    q.push(node->child(j));
                }
            }
        }
    }
    std::cout << n << "\n";
    

    【讨论】:

      猜你喜欢
      • 2016-03-18
      • 1970-01-01
      • 2011-03-12
      • 1970-01-01
      • 2011-09-30
      • 2021-01-27
      • 1970-01-01
      • 2011-05-15
      • 1970-01-01
      相关资源
      最近更新 更多