如何将普通二叉树转换为“更智能”的二叉树,其中每个节点都知道其父节点、子节点总数和级别?
Posted
技术标签:
【中文标题】如何将普通二叉树转换为“更智能”的二叉树,其中每个节点都知道其父节点、子节点总数和级别?【英文标题】:How do I transfer a normal binary tree into a "smarter" binary tree where each node knows its parents, total subnodes and level? 【发布时间】:2015-02-05 14:55:12 【问题描述】:我仍然习惯于数据结构,并且我对以各种方式遍历二叉树感到满意,但我现在遇到的情况是,我有一个正常的二叉树,由只知道的节点构成具有data
、left
和right
属性。
但是,我想将其转换为“更智能”的二叉树。这棵树要知道它的父节点,它的总子节点,以及它在总树中的层级。
我真的很纠结如何将一棵“笨”树转移到更智能的版本中。我的第一个直觉是递归遍历,但我不确定如何区分父级和级别。
【问题讨论】:
【参考方案1】:将旧树复制到新树,使用正常的递归方法遍历原树。
由于您要向节点添加新属性,我认为您需要使用新属性的字段构造新节点。
定义一个递归函数来复制以给定节点为根的(子)树。它需要其深度和父级作为输入。 (当然,父节点必须是它在新树中的父节点。)让它返回新(子)树的根。
function copy_node (old_node, new_parent, depth) -> returns new_node
new_node = new node
new_node.data = old_root.data // whatever that data might be
new_node.depth = depth
new_node.parent = parent
new_node.left = copy_node (old_node.left, new_node, depth + 1)
new_node.right = copy_node (old_node.right, new_node, depth + 1)
return new_node
复制整棵树
new_tree = copy_node (old_tree, nil, 0)
如果您使用的语言可以随意将字段添加到现有对象,您甚至不必进行额外的复制:
function adorn_node (node, parent, depth)
node.parent = parent
node.depth = depth
adorn_node (node.left, node, depth + 1)
adorn_node (node.right, node, depth + 1)
然后开始滚动
adorn_node (root, nil, 0)
话虽如此,您可能会发现大多数二叉树实现不包含这些额外字段是有充分理由的。在您想要在树上执行的许多不同操作中维护它们是很多工作。 深度,尤其是当您需要重新平衡树时,很难保持正确。
而且这些领域通常不会给你买任何东西。大多数对树进行操作的算法都是使用递归函数来实现的,从上面的示例中可以看出,在运行时重新计算 parent 和 depth 非常容易你在树上散步。它们不需要存储在节点本身中。
树平衡通常需要知道左右子树的高度差。 (“depth”是到根的距离;“height”是到子树中最远叶节点的距离。) height 在从根向下的过程中并不那么容易计算,但幸运的是,您通常只对哪个子树具有最大 高度 感兴趣,为此,通常只在每个节点中存储值 -1、0、+1 就足够了。
【讨论】:
以上是关于如何将普通二叉树转换为“更智能”的二叉树,其中每个节点都知道其父节点、子节点总数和级别?的主要内容,如果未能解决你的问题,请参考以下文章
2021-10-07:将有序数组转换为二叉搜索树。给你一个整数数组 nums ,其中元素已经按 升序 排列,请你将其转换为一棵 高度平衡 二叉搜索树。高度平衡 二叉树是一棵满足「每个节点的左右两个子树