# Definition for a binary tree node.
# class TreeNode(object):
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Codec:
def serialize(self, root):
"""Encodes a tree to a single string.
:type root: TreeNode
:rtype: str
"""
res=''
def dfs_help(root ):
nonlocal res
if not root :
if len(res)==0:
res +='N'
return
else:
res +=',N'
return
if len(res)==0:# 定位是头节点
res += str(root.val)
else:
res += f',{str(root.val)}'
dfs_help(root.left)
dfs_help(root.right)
dfs_help(root )
return res
def deserialize(self, data):
"""Decodes your encoded data to tree.
:type data: str
:rtype: TreeNode
"""
index =0
nodes= data.split(',')
def dfs_help(nodes):
nonlocal index
if nodes[index]=='N':
index +=1
return None
node =TreeNode(int(nodes[index]))
index +=1
node.left= dfs_help(nodes)
node.right=dfs_help(nodes)
return node
res =dfs_help(nodes)
return res
"""
该类包含将二叉树序列化为字符串,并将字符串反序列化为二叉树的方法。
序列化/反序列化方法采用基于先序遍历 (Pre-order Traversal) 的深度优先搜索 (DFS)。
"""
def serialize0(self, root: Optional[TreeNode]) -> str:
"""
将二叉树编码(序列化)为一个用逗号分隔的字符串。
使用先序遍历 (根-左-右) 的顺序。空节点用特殊字符 'N' 表示。
:type root: TreeNode
:rtype: str
"""
# res 用于累积构建序列化后的字符串
res = ''
# 定义一个嵌套的 DFS 辅助函数来进行遍历和构建字符串
def dfs_help(node: Optional[TreeNode]):
# 使用 nonlocal 关键字允许内部函数修改外部函数定义的变量 res
nonlocal res
# 1. 基线条件:如果当前节点为空 (None)
if not node:
# 如果 res 当前为空 (意味着这是第一个节点,即整棵树为空)
if len(res) == 0:
# 直接添加 'N'
res += 'N'
return
else:
# 如果 res 不为空,说明这是某个节点的子节点为空,
# 需要先添加逗号分隔符,再添加 'N'
res += ',N'
return
# 2. 处理当前节点 (根节点) - 先序遍历的核心
# 如果 res 当前为空 (说明这是整棵树的根节点)
if len(res) == 0:
# 直接添加根节点的值 (转换为字符串)
res += str(node.val)
else:
# 如果 res 不为空,说明这不是第一个节点,需要先加逗号分隔符
res += f',{str(node.val)}' # 使用 f-string 添加逗号和节点值
# 3. 递归处理左子树
dfs_help(node.left)
# 4. 递归处理右子树
dfs_help(node.right)
# 从根节点开始执行 DFS 序列化
dfs_help(root)
# 返回最终构建的序列化字符串
return res
def deserialize0(self, data: str) -> Optional[TreeNode]:
"""
将之前编码(序列化)的字符串解码(反序列化)为二叉树。
根据先序遍历的顺序重建树。
:type data: str
:rtype: TreeNode
"""
# index 用于在 nodes 列表中跟踪当前应该处理哪个元素
# 使用 nonlocal 允许嵌套函数修改它
index = 0
# 将输入的字符串按逗号分割成节点值(或'N')的列表
nodes = data.split(',')
# 定义一个嵌套的 DFS 辅助函数来进行递归构建树
def dfs_help(nodes_list: List[str]) -> Optional[TreeNode]:
# 使用 nonlocal 关键字允许内部函数修改外部函数定义的变量 index
nonlocal index
# 1. 处理空节点标记 'N'
# 如果当前索引指向的元素是 'N'
if nodes_list[index] == 'N':
# 消耗掉这个 'N' (索引向后移动一位)
index += 1
# 返回 None,表示这里是一个空子树
return None
# 2. 创建当前节点
# 根据当前索引处的字符串值创建一个新的 TreeNode。
# 注意需要将字符串转换为整数。
node = TreeNode(int(nodes_list[index]))
# 3. 消耗掉当前节点的值 (索引向后移动一位)
index += 1
# 4. 递归构建左子树
# 因为是先序遍历序列化的,所以接下来列表中的元素属于左子树。
# 递归调用 dfs_help 会处理左子树的所有节点(包括其中的'N'),
# 并正确地移动 index。
node.left = dfs_help(nodes_list)
# 5. 递归构建右子树
# 当左子树的递归调用返回后,index 已经指向右子树的第一个元素(或'N')。
# 递归调用 dfs_help 来构建右子树。
node.right = dfs_help(nodes_list)
# 6. 返回当前构建好的节点(及其已连接好的左右子树)
return node
# 从 nodes 列表的开头开始执行 DFS 反序列化
root = dfs_help(nodes)
# 返回构建好的整棵树的根节点
return root
# Your Codec object will be instantiated and called as such:
# ser = Codec() # 创建序列化器实例
# deser = Codec() # 创建反序列化器实例
# root = ... # (假设这里有一个 TreeNode 对象)
# serialized_string = ser.serialize(root) # 将树序列化为字符串
# deserialized_root = deser.deserialize(serialized_string) # 将字符串反序列化回树
# ans = deserialized_root # 得到反序列化后的根节点
# Your Codec object will be instantiated and called as such:
# ser = Codec()
# deser = Codec()
# ans = deser.deserialize(ser.serialize(root))
297. 二叉树的序列化与反序列化 比较难的题目
于 2025-04-08 22:28:40 首次发布