题目来自LeetCode,链接:面试题37. 序列化二叉树。具体描述为:实现两个函数,分别用来序列化和反序列化二叉树。
示例:
你可以将以下二叉树:
1
/ \
2 3
/ \
4 5
序列化为 "[1,2,3,null,null,4,5]"
可以按照示例的序列化方式(也可以用其他的方法,题目只是说可以用示例的方法而已),其实就是将层序遍历的结果输出为字符串,层序遍历直接套模板就好了:
- 根节点入队列,非空节点数
nodeCount
加1 - 只要非空节点数
nodeCount
大于0,就执行下面的循环- 出队一个节点
node
- 如果
node
为空,序列化字符串加上一个null
- 如果
node
不为空,非空节点数nodeCount
减1,node
的左右子节点均入队列,而且非空节点数nodeCount
需要加上非空子节点的数量
- 出队一个节点
时间复杂度是 O ( n ) O(n) O(n),空间复杂度为 O ( n ) O(n) O(n)。
至于反序列化,其实就是上面层序遍历过程的一个反过程:
- 把字符串根据分隔符(比如逗号)给恢复成字符串数组
strs
,初始化索引变量idx=1
- 先建立根节点,根节点值就是
strs[0]
对应的数值,根节点入队 - 只要
idx
未越界,执行以下循环:- 出队一个节点
node
- 如果
strs[idx]
不是null
值,则新建一个以strs[idx]
为val
的节点,赋值给node.left
并加入队列,idx
加1 - 如果
idx
未越界且strs[idx]
不是null
值,则新建一个以strs[idx]
为val
的节点,赋值给node.right
并加入队列,idx
加1
- 出队一个节点
JAVA版代码如下:
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
public class Codec {
// Encodes a tree to a single string.
public String serialize(TreeNode root) {
if (root == null) {
return "[]";
}
Queue<TreeNode> queue = new LinkedList<>();
queue.offer(root);
int nodeCount = 1;
StringBuilder sb = new StringBuilder("[");
while (nodeCount > 0) {
TreeNode node = queue.poll();
if (node == null) {
sb.append("null,");
}
else {
sb.append(node.val + ",");
--nodeCount;
queue.offer(node.left);
if (node.left != null) {
++nodeCount;
}
queue.offer(node.right);
if (node.right != null) {
++nodeCount;
}
}
}
sb.deleteCharAt(sb.length() - 1);
sb.append("]");
return sb.toString();
}
// Decodes your encoded data to tree.
public TreeNode deserialize(String data) {
if (data.equals("[]")) {
return null;
}
String[] strs = data.substring(1, data.length() - 1).split(",");
Queue<TreeNode> queue = new LinkedList<>();
TreeNode root = new TreeNode(Integer.parseInt(strs[0]));
queue.offer(root);
int idx = 1;
while (idx < strs.length) {
TreeNode node = queue.poll();
if (!strs[idx].equals("null")) {
node.left = new TreeNode(Integer.parseInt(strs[idx]));
queue.offer(node.left);
}
++idx;
if (idx < strs.length && !strs[idx].equals("null")) {
node.right = new TreeNode(Integer.parseInt(strs[idx]));
queue.offer(node.right);
}
++idx;
}
return root;
}
}
// Your Codec object will be instantiated and called as such:
// Codec codec = new Codec();
// codec.deserialize(codec.serialize(root));
提交结果如下:
![](https://img-blog.csdnimg.cn/20200601203139588.png)
Python版代码如下:
# 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 '[]'
res = []
queue = collections.deque()
nodeCount = 1
queue.append(root)
while nodeCount > 0:
node = queue.popleft()
if not node:
res.append('null')
else:
nodeCount -= 1
res.append(str(node.val))
queue.append(node.left)
if node.left:
nodeCount += 1
queue.append(node.right)
if node.right:
nodeCount += 1
return '[' + ','.join(res) + ']'
def deserialize(self, data):
"""Decodes your encoded data to tree.
:type data: str
:rtype: TreeNode
"""
if data == '[]':
return None
datas = data[1 : -1].split(',')
n = len(datas)
queue = collections.deque()
root = TreeNode(int(datas[0]))
queue.append(root)
idx = 1
while idx < n:
node = queue.popleft()
if datas[idx] != 'null':
node.left = TreeNode(int(datas[idx]))
queue.append(node.left)
idx += 1
if idx < n and datas[idx] != 'null':
node.right = TreeNode(int(datas[idx]))
queue.append(node.right)
idx += 1
return root
# Your Codec object will be instantiated and called as such:
# codec = Codec()
# codec.deserialize(codec.serialize(root))
提交结果如下:
![](https://img-blog.csdnimg.cn/2020060121152962.png)