本文已参与「新人创作礼」活动, 一起开启掘金创作之路。
297. 二叉树的序列化与反序列化
来源:力扣(LeetCode)
序列化是将一个数据结构或者对象转换为连续的比特位的操作,进而可以将转换后的数据存储在一个文件或者内存中,同时也可以通过网络传输到另一个计算机环境,采取相反方式重构得到原数据。
请设计一个算法来实现二叉树的序列化与反序列化。这里不限定你的序列 / 反序列化算法执行逻辑,你只需要保证一个二叉树可以被序列化为一个字符串并且将这个字符串反序列化为原始的树结构。
提示: 输入输出格式与 LeetCode 目前使用的方式一致,详情请参阅 LeetCode 序列化二叉树的格式。你并非必须采取这种方式,你也可以采用其他的方法解决这个问题。
示例 1:
输入:root = [1,2,3,null,null,4,5]
输出:[1,2,3,null,null,4,5]
示例 2:
输入:root = []
输出:[]
示例 3:
输入:root = [1]
输出:[1]
示例 4:
输入:root = [1,2]
输出:[1,2]
提示:
- 树中结点数在范围 [0, ] 内
- -1000 <= Node.val <= 1000
解法
树的序列化与反序列化,自己设定序列化规则与反序列化规则,这里以先序遍历为序列化规则,根左右;先序遍历有递归和迭代两种方式,这里以递归和层序遍历为解题方法。
-
递归:从根节点开始,然后就是左子节点,然后就是右子节点,最后将其拼接为一个字符串,注意中间要保存空节点;
-
bfs循环: bfs层序遍历,先根节点,然后根节点的左右节点加入队列中;
代码实现
递归
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
"""
res = []
def helper(node):
if not node:
res.append(node)
else:
res.append(node.val)
helper(node.left)
helper(node.right)
helper(root)
string = ''
for node in res:
string += str(node) + ','
return string
def deserialize(self, data):
"""Decodes your encoded data to tree.
:type data: str
:rtype: TreeNode
"""
def helper(ss):
if ss[0] == 'None':
ss.pop(0)
return None
root = TreeNode(ss.pop(0))
root.left = helper(ss)
root.right = helper(ss)
return root
return helper(data.split(','))
# Your Codec object will be instantiated and called as such:
# ser = Codec()
# deser = Codec()
# ans = deser.deserialize(ser.serialize(root))
c++实现
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Codec {
public:
void reserialize(TreeNode* root, string& str) {
if (root == nullptr)
str += "None,";
else {
str += to_string(root->val) + ",";
reserialize(root->left, str);
reserialize(root->right, str);
}
}
// Encodes a tree to a single string.
string serialize(TreeNode* root) {
string ret;
reserialize(root, ret);
return ret;
}
TreeNode* rdeserialize(list<string>& dataAarray) {
if (dataAarray.front() == "None") {
dataAarray.erase(dataAarray.begin());
return nullptr;
}
TreeNode* root = new TreeNode(stoi(dataAarray.front()));
dataAarray.erase(dataAarray.begin());
root->left = rdeserialize(dataAarray);
root->right = rdeserialize(dataAarray);
return root;
}
// Decodes your encoded data to tree.
TreeNode* deserialize(string data) {
list<string> dataAarray;
string str;
for (auto& ch: data) {
if (ch == ',') {
dataAarray.push_back(str);
str.clear();
}
else
str.push_back(ch);
}
if (!str.empty()) {
dataAarray.push_back(str);
str.clear();
}
return rdeserialize(dataAarray);
}
};
// Your Codec object will be instantiated and called as such:
// Codec ser, deser;
// TreeNode* ans = deser.deserialize(ser.serialize(root));
复杂度分析
- 时间复杂度: 每个节点都遍历一次
- 空间复杂度: 递归栈空间每节点
BFS循环
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 '[]'
# bfs
res = []
queue = [root]
while queue:
node = queue.pop(0)
res.append(node.val) if node else res.append('null')
if node:
queue.append(node.left) if node.left else queue.append(None)
queue.append(node.right) if node.right else queue.append(None)
res = [str(i) for i in res]
while res[-1] == 'null':
res.pop()
return '[' + ','.join(res) + ']'
def deserialize(self, data):
"""Decodes your encoded data to tree.
:type data: str
:rtype: TreeNode
"""
if data == '[]':
return None
vals = data[1: -1].split(',')
root = TreeNode(int(vals[0]))
i = 1
queue = [root]
length = len(vals)
while queue:
node = queue.pop(0)
if i < length and vals[i] != 'null':
node.left = TreeNode(int(vals[i]))
queue.append(node.left)
i += 1
if i < length and vals[i] != 'null':
node.right = TreeNode(int(vals[i]))
queue.append(node.right)
i += 1
return root
# Your Codec object will be instantiated and called as such:
# codec = Codec()
# codec.deserialize(codec.serialize(root))
c++实现
class Codec {
public:
// Encodes a tree to a single string.
string serialize(TreeNode* root) {
// 层序遍历 BFS
string ret;
queue<TreeNode*> que;
que.emplace(root);
while (!que.empty()) {
int size = que.size();
for (int i = 0; i < size; i++) {
TreeNode* node = que.front();
que.pop();
// 空节点直接加入"None,"
if (node == NULL) ret += "None,";
else {
// 加入节点val,并依次遍历左右子树
ret += to_string(node->val) + ",";
que.emplace(node->left);
que.emplace(node->right);
}
}
}
return ret;
}
// Decodes your encoded data to tree.
TreeNode* deserialize(string data) {
if (data.size() == 0) return NULL;
list<string> dataArray;
string str;
for (auto& c : data) {
if (c == ',') {
dataArray.emplace_back(str);
str.clear();
} else {
str.push_back(c);
}
}
if (str.size() != 0) {
dataArray.emplace_back(str);
str.clear();
}
queue<TreeNode*> que;
if (dataArray.front() == "None") return NULL;
TreeNode* root = new TreeNode(stoi(dataArray.front()));
que.emplace(root);
dataArray.pop_front();
while (!que.empty() && !dataArray.empty()) {
int size = que.size();
for (int i = 0; i < size && !dataArray.empty(); i++) {
TreeNode* cur = que.front(); // 父节点
que.pop();
// 第一个为左节点
if (dataArray.front() != "None") {
TreeNode* node1 = new TreeNode(stoi(dataArray.front()));
cur->left = node1;
que.push(node1);
}
dataArray.pop_front();
// 第二个为右节点
if (dataArray.front() != "None") {
TreeNode* node2 = new TreeNode(stoi(dataArray.front()));
cur->right = node2;
que.push(node2);
}
dataArray.pop_front();
}
}
return root;
}
};
复杂度分析
- 时间复杂度:
- 空间复杂度: