序列化是将一个数据结构或者对象转换为连续的比特位的操作,进而可以将转换后的数据存储在一个文件或者内存中,同时也可以通过网络传输到另一个计算机环境,采取相反方式重构得到原数据。
请设计一个算法来实现二叉树的序列化与反序列化。这里不限定你的序列 / 反序列化算法执行逻辑,你只需要保证一个二叉树可以被序列化为一个字符串并且将这个字符串反序列化为原始的树结构。
示例:
你可以将以下二叉树:
1
/ \
2 3
/ \
4 5
序列化为 "[1,2,3,null,null,4,5]"
1、题目分析
本题的题意比较清晰名了,分为两部分:
①序列化:就是把一个二叉树进行层次遍历把所有节点都存起来即使是空节点
②反序列化:就是把一个数组转换成二叉树的形式
其实说白了,就是一个构造,一个遍历就完了。
2、解题分析
不管序列化还是序列化,首先判断初始的列表或者根节点是否为空。
-
序列化
-
其实就是一个BFS遍历而已,首先声明一个队列,把根节点添加到队列中去
-
如果队列为空,直接返回结果
-
如果队列不为空,取出节点
-
如果节点非空,把节点的值添加到结果列表中,在依次把这个节点的左右节点添加到队列
-
节点为空就把‘null’加入到结果列表中去
-
-
-
反序列化
-
把列表的第一个元素设为根节点,并将根节点添加到队列中去
-
如果队列为空直接返回结果
-
如果队列非空
-
下一个节点是不是为null,如果不是把这个节点也加入到根节点的左节点,并且把这个左节点加入到队列中去
-
下下个节点同理,不过加入到有节点中去
-
知道把给定的列表遍历完,队列为空的时候返回结果
-
-
代码如下:
# 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
"""
#层次遍历一个二叉树不管是不是空节点都输出
if not root:
return "[]"
queue = collections.deque()
queue.append(root)
res = []
while queue:
node = queue.popleft()
#节点为为空,res添加null,否则添加node.val
if node:
res.append(str(node.val))
queue.append(node.left)
queue.append(node.right)
else: res.append("null")
return '[' + ','.join(res) + ']'
def deserialize(self, data):
"""Decodes your encoded data to tree.
:type data: str
:rtype: TreeNode
"""
#按照层次遍历的输出去构造一个二叉树,遵循先左后右
if data=='[]':
return None
vals, i = data[1:-1].split(','), 1
root = TreeNode(int(vals[0]))
queue = collections.deque()
queue.append(root)
while queue:
node = queue.popleft()
if vals[i] != "null":
node.left = TreeNode(int(vals[i]))
queue.append(node.left)
i += 1
if vals[i] != "null":
node.right = TreeNode(int(vals[i]))
queue.append(node.right)
i += 1
print(root)
return root
# Your Codec object will be instantiated and called as such:
# codec = Codec()
# codec.deserialize(codec.serialize(root))
总结:序列化和序列化是相反的两个操作,一个是遍历树,一个是构造树。