题目描述
请实现两个函数,分别用来序列化和反序列化二叉树。
你需要设计一个算法来实现二叉树的序列化与反序列化。这里不限定你的序列 / 反序列化算法执行逻辑,你只需要保证一个二叉树可以被序列化为一个字符串并且将这个字符串反序列化为原始的树结构。
简化题目
这题实际上就是给了两个函数A和B。
A的功能:给树的root,输出str类型的层次遍历结果。
B的功能:给str类型的层次遍历结果,构造树。
不过这里的层次遍历需要加上null。
比如下面这张图,输出结果就是:[1,2,3,null,null,4,5]
思路分析
通常使用的前序、中序、后序、层序遍历记录的二叉树的信息不完整,即唯一的输出序列可能对应着多种二叉树可能性。题目要求的 序列化 和 反序列化 是 可逆操作 。因此,序列化的字符串应携带 完整的二叉树信息 。
也就是要加上叶子结点的null在对应的位置。
一、A函数:给树root,输出字符串。
这个比较容易,就是层次遍历就行了,遇到空节点记得加入null。
最后在return的时候要注意,人家要的是字符串型列表。
ef serialize(self, root):
if not root:
return '[]'
queue = []
res = []
queue.append(root)
while queue:
node = queue.pop()
if node:
res.append(str(node.val))
queue.insert(0,node.left)
queue.insert(0,node.right)
else:
res.append("null")
return '[' + ','.join(res) + ']'
二、B函数:给字符串,构造树
该函数给的是字符串。所以要先提取出来列表方便后面使用。
vals = data[1:-1].split(",")
假设题目所给字符串下图所示:
设置一个 i 变量来遍历vals。
与传统构造树的方法基本一样。
当vals[i] 为非null的时候,构造树。
为null的时候,i往后挪,不做其余操作。
可以这样理解,对于叶子节点,其左右都是null。每次构造一个节点,就判断下一个
vals[i] 的值是否为null,若为null就不构造子树,i 继续往后挪。
当左右子树都判断完了,就继续下一轮循环,重新从队列中取出新的节点。
看下面这张图帮助理解:
此时 i 指向第一个null,既在循环中判断vals[I] 为null,则不构建节点2的左子树,i往后挪,继续判断,又是null,就不构建 节点2 的右子树 ,i 继续往后。
后面又进行新一轮的while,从队列中取出新的节点3,再次判断vals[i]。。。。以此列推
def deserialize(self, data):
if data == '[]':
return
i = 1
queue = []
vals = data[1:-1].split(",") # 提取列表
root = TreeNode(val = vals[0]) # 构造根节点
queue.append(root)
while queue:
node = queue.pop()
if vals[i] != "null":
node.left = TreeNode(val = int(vals[i]))
queue.insert(0,node.left)
i+=1
if vals[i] !="null":
node.right = TreeNode(val=int(vals[i]))
queue.insert(0,node.right)
i+=1
return root