序列化与反序列化主要分为两个流派:dfs和bfs;由于二叉树的特殊性,dfs分为前序、中序、后序遍历,但只有前序和后序遍历才可以在线性复杂度下进行反序列化。
事实上,也可以利用非递归的方式进行dfs前、中、后序遍历,但都较难以归并到同一个函数下,故此处省略,若有兴趣可参考此出:【面试】算法:二叉树非递归形式的遍历及层级遍历。
实际上先序遍历和后序遍历的反序列化可以归于同一个框架下,但为了代码简洁可读我把它拆分成了两段代码,二者的本质是栈状态的初始化和扫描方向不同。
要想进行反序列化,需要有两个充要条件:1.知道根节点的位置;2.知道序列化的方法及何处为空节点。 显然,只有先序和后序遍历出来的序列才能满足条件1(先序根节点在序列的第一位、后序在末尾);而中序显然就很难进行确认根节点在何处。
def deserialize_dfs_pre(string: str): # 先序反序列化 strings = string.split(',') index = -1 # 控制栈状态 def dfs(): nonlocal index # 在其他语言里,请把理解为 nonlocal => global 或 Class.static index += 1 if strings[index] == '#': return None node = TreeNode(int(strings[index])) node.left, node.right = dfs(), dfs() return node return dfs() def deserialize_dfs_pos(string: str): # 后序反序列化 strings = string.split(',') index = len(strings) - 1 # 由于split(','),最后一位是'',因此从len(strings) - 1开始 def dfs(): nonlocal index index -= 1 if strings[index] == '#': return None node = TreeNode(int(strings[index])) node.right, node.left = dfs(), dfs() # 注意先右后左 return node return dfs()