-
森林与二叉树的转换
-
森林转二叉树的过程遵循以下规则:
- 将森林中的每一棵树独立地转换为对应的二叉树(即保留每个节点的第一个孩子作为左子树,其余兄弟作为该孩子的右链)。
- 将第一棵树的根节点作为最终二叉树的根。
- 后续每棵树都作为前一棵树对应二叉树根节点的右子树连接起来。例如,第二棵树成为第一棵树根的右子树,第三棵树成为第二棵树在右子树位置上的右子树,依此类推。
这样形成的二叉树,其左子树代表原树的子孙结构,右子树链则表示兄弟关系或不同树之间的连接。
-
二叉树转森林/树的方法是逆向还原:
- 若一个节点有右子树,则说明它在原始结构中有“兄弟”或属于另一棵树。
- 沿着每个节点的右指针拆分,将右子树分离出来作为独立的树处理。
- 最终得到一组互不相连的树,构成森林;如果整个二叉树没有被拆分为多个部分(即根无右子树),则还原为单一的树。
该转换基于“左孩子-右兄弟”表示法,是一种逻辑映射方式,便于用二叉树结构存储和操作森林。
-
-
图的结构特点
图是由顶点集合和边集合组成的非线性数据结构,具有如下特性:- 任意两个顶点之间都可能存在关系,不像线性结构仅前后相邻,也不像树结构限制父子层级。
- 每个顶点可以有多个前驱和多个后继,甚至自身也可以形成回路(环)。
- 相较于其他结构:
- 线性结构(如数组、链表)中,除首尾外,每个元素只有一个直接前驱和一个直接后继,体现“一对一”关系。
- 树结构体现“一对多”关系,每个节点最多一个双亲(前驱),但可有多个孩子(后继),存在层次性。
- 图结构体现“多对多”关系,无固定层次,结构自由度最高,适用于表达复杂网络(如社交网络、交通网等)。
因此,图是最具通用性和灵活性的数据结构之一。
# 示例:森林转二叉树(简化模拟)
class TreeNode:
def __init__(self, val=0):
self.val = val
self.left = None
self.right = None
def forest_to_binary_tree(trees):
if not trees:
return None
# 假设 trees 是每棵树的根节点列表
prev_root = None
for root in reversed(trees): # 从最后一棵开始构建右链
root.right = prev_root
prev_root = root
return trees[0] # 第一棵树的根为总根
实现“左孩子-右兄弟”表示法将普通树转化为二叉树的核心思想是:
每个节点的第一个孩子(最左边的孩子)作为其左子树,而该节点的其他兄弟节点依次链接在其右子树上,形成一个向右延伸的链表结构。
转换规则:
- 左指针指向该节点的第一个孩子;
- 右指针指向该节点的下一个兄弟;
- 这样,一棵多叉树就可以唯一地转换为一棵二叉树。
实现步骤(递归方式):
- 对当前节点的所有子节点进行处理。
- 将第一个子节点作为当前节点的左子树。
- 其余子节点按照从左到右顺序,逐个作为前一个子节点的右子树(即兄弟连接)。
- 递归处理每一个子节点的孩子。
Python 示例代码:
class MultiTreeNode:
def __init__(self, val=0):
self.val = val
self.children = [] # 存储多个孩子节点
class BinaryTreeNode:
def __init__(self, val=0):
self.val = val
self.left = None # 第一个孩子
self.right = None # 下一个兄弟
def convert_to_binary_tree(root):
if not root:
return None
# 创建对应的二叉树节点
binary_root = BinaryTreeNode(root.val)
# 如果有孩子,将第一个孩子作为左子树
if root.children:
first_child = root.children[0]
binary_root.left = convert_to_binary_tree(first_child)
# 将其余兄弟连接为右子树链
current = binary_root.left
for sibling in root.children[1:]:
current.right = convert_to_binary_tree(sibling)
current = current.right
return binary_root
示例说明:
假设有一棵多叉树结构如下:
A
/ | \
B C D
/ \
E F
使用“左孩子-右兄弟”表示法后,对应的二叉树为:
A
/
B
/ \
E C
/ \
F D
解释:
- A 的左孩子是 B(第一个孩子),C 和 D 是 B 的“兄弟”,通过右指针链接。
- B 的左孩子是 E,F 是 E 的兄弟,所以 F 是 E 的右子树。
总结:
这种转换保持了原树的父子与兄弟关系,使得可以用二叉树结构来存储和操作任意的树或森林,广泛应用于树形结构的内存表示中。



被折叠的 条评论
为什么被折叠?



