当前位置: 首页 > 知识库问答 >
问题:

二叉树中最大的完整子树

叶茂
2023-03-14

我将完整子树定义为所有级别都已满且最后一个级别左对齐的树,即所有节点都尽可能左对齐,我希望找到树中最大的完整子树。

一种方法是对每个节点作为根执行这里概述的方法,这将花费O(n^2)时间。

有更好的方法吗?

共有3个答案

郭易安
2023-03-14

定义树节点的秩,如果此节点是根节点,则将其定义为最大完整子树的高度。如果节点是根节点,则将节点宽度定义为“最大完整子树”最后一级中的节点数。所以对于树中的每个节点,我们有两个编号(r,w)。和w

若节点有零个子节点或只有一个子节点,则节点有(r,w)=(1,1)

如果节点有两个子节点(r1,w1)(r2,w2),我们有几种情况:

  1. r1

         root     
         ....
    /  \     /   \
   l    l    r    r
  /\   /    /\    /
  l l  l    r r  r

最大完全子树是


          m     
         ....
    /  \     /   \
   m    m    m    m
  /\   /    /\    /
  m m  m    r r  r

         root     
         ....
    /  \      /   \
   l    l     r    r
  /\   / \    /\    /\
  l l  l  l   r r  r  r
             /
            r

最大完全子树是


          m     
         ....
    /  \      /   \
   m    m     m    m
  /\   / \    /\    /\
 m  m  m  m   m m  m  m
             /
            r

例子:


         root     
         ....
    /  \      /   \
   l    l     r    r
  /\   /      /\    /\
  l l  l      r r  r  r
             /
            r

最大完全子树是


          m     
         ....
    /  \      /   \
   m    m     m    m
  /\   /     /\    /\
 m  m  m     r r  r  r
            /
            r

基于此规则,您可以使用递归为每个节点计算(r,w)。这将需要O(n)。当您在这些节点中找到具有最大秩r的节点时,请查找具有最大秩w的节点,并且该节点应该是一个解决方案。

秦城
2023-03-14

这是我的Python解决方案。它正在处理我提出的案子。返回值的含义如下:[x,y,z]

>

  • x=此节点之前最大完整子树的大小
  • y=子树的高度
  • z:0-完整子树,1-此子树中只有一个节点具有左子树,2-不是完整子树

    def largest_complete_tree(root):
    
        result = traverse_complete(root)
        print('largest complete subtree: {}'.format(result[0]))
    
    def traverse_complete(root):
        if root:
            left = traverse_complete(root.left)
            right = traverse_complete(root.right)
            max_complete = max(left[0], right[0])
            max_height = max(left[1], right[1])
            left_child_only = 1 if (left[2] == 1 and right[0] == 0) or (left[0] == 1 and right[0] == 0) else 0
    
            # 5 conditions need to pass before left and right can be joined by this node
            # to create a complete subtree.
            if left[0] < right[0]:
                return [max_complete, 0, 2]
            if left[2] == 2 or right[2] == 2:
                return [max_complete, 0, 2]
            if abs(left[1]-right[1]) > 1:
                return [max_complete, 0, 2]
            if (left[2] == 1 and right[2] == 1) or (left[2] == 0 and right[2] == 1):
                return [max_complete, 0, 2]
            if left[0] == right[0] and left[0] != 2**left[0] - 1:
                return [max_complete, 0, 2]
            return [left[0] + right[0] + 1, max_height + 1, left_child_only]
        else:
            return [0,0,0]
    

  • 蔚琦
    2023-03-14

    因为上面没有C解决方案,所以我添加了我的解决方案。让我知道,如果你觉得有什么不正确的或任何可以改进。

    struct CompleteStatusWithHeight {
     bool isComplete;
     int height;
    };
    
    int FindLargestCompletetSubTreeSize(const unique_ptr<BinaryTreeNode<int>>& tree)
    {
      return CheckComplete(tree).height;
    }
    
    CompleteStatusWithHeight CheckComplete(const unique_ptr<BinaryTreeNode<int>>& tree)
    {
    if (tree == nullptr) {
           return {true, -1};  // Base case.
    }
    
    auto left_result = CheckComplete(tree->left);
    if (!left_result.isComplete) {
      return {false, 0};  // Left subtree is not balanced.
    }
    auto right_result = CheckComplete(tree->right);
    if (!right_result.isComplete) {
      return {false, 0};  // Right subtree is not balanced.
    }
    
    bool is_balanced = abs(left_result.height - right_result.height) == 0;
    bool is_left_aligned = (left_result.height - right_result.height) == 1;
    bool is_leaf =  left_result.height  == -1 && right_result.height ==-1;
    bool is_complete = is_balanced || is_left_aligned || is_leaf;
    
    int height = max(left_result.height, right_result.height) + 1;
    return {is_complete, height};
    }
    
     类似资料:
    • 问题内容: 我对二叉树有一些疑问: Wikipedia指出,当“完整的二叉树是其中所有级别(可能除了最后一个级别)均已完全填充且所有节点都位于最左侧”的二叉树时,该二叉树即已 完成 。最后的“越远越好”的段落是什么意思? 如果(1)它是空的,或者(2)它的左右子级是平衡的,并且左树的高度在以下高度的1之内,则格式正确的二叉树被称为“高度平衡”。正确的树,取自如何确定二叉树是否平衡?,这是正确的还是

    • 考虑二叉树,其中每个节点要么是叶,要么正好有两个子节点(左和右,我们认为不同)。在节点上有多少不同的树 例如: -3个节点-

    • 给定一个包含n个节点的完整二叉树,一个节点的平均后代数是多少?例如,根节点有n-1个子节点,每个叶节点有0个子节点,但是考虑到所有节点,平均值是多少?

    • 下面给出了二叉树的实现。 如图中所示,树不是完整的二叉树。如何编写一个函数,将上述二叉树转换为完整的二叉树,只需将字符串数据节点添加到没有子节点的节点,即可生成完整的二叉树。 我将手动在代码中添加节点,以获得如下结果树: 但是,如何编写一个函数,它将采取根节点和返回树,这是完整的二叉树。

    • 计算二叉树最大的宽度 根据带虚结点的先序序列建立二叉树,计算该二叉树最大的宽度(二叉树的最大宽度是指二叉树所有层中结点个数的最大值)并输出。 输入格式: 测试数据有多组,处理到文件尾。每组测试数据在一行中输入一个字符串(不含空格且长度不超过80),表示二叉树的先序遍历序列,其中字符*表示虚结点(对应的子树为空)。 输出格式: 对于每组测试,输出二叉树的最大宽度。输出格式为:“maxWidth: m

    • 这道题是 LeetCode 124 题。 给定一个非空二叉树,返回其最大路径和。注意,这里的“路径”并非自顶向下的单向路径,而是二叉树中任意连通的路径,可以在任一节点开始和结束。比如对于下图的二叉树,10->12->9 是一个最大路径: -9 / \ 1 12 / \ 10 9 分析 首先定义“端点”的概念。一条路径有两个端点:起点和终点。比如上述示例中,