我将完整子树定义为所有级别都已满且最后一个级别左对齐的树,即所有节点都尽可能左对齐,我希望找到树中最大的完整子树。
一种方法是对每个节点作为根执行这里概述的方法,这将花费O(n^2)时间。
有更好的方法吗?
定义树节点的秩,如果此节点是根节点,则将其定义为最大完整子树的高度。如果节点是根节点,则将节点宽度定义为“最大完整子树”最后一级中的节点数。所以对于树中的每个节点,我们有两个编号(r,w)
。和w
若节点有零个子节点或只有一个子节点,则节点有
(r,w)=(1,1)
。
如果节点有两个子节点
(r1,w1)
和(r2,w2)
,我们有几种情况:
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
的节点,并且该节点应该是一个解决方案。
这是我的Python解决方案。它正在处理我提出的案子。返回值的含义如下:[x,y,z]
>
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]
因为上面没有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 分析 首先定义“端点”的概念。一条路径有两个端点:起点和终点。比如上述示例中,