请实现两个函数,分别用来序列化和反序列化二叉树。
示例:
你可以将以下二叉树:
1
/ \
2 3
/ \
4 5
序列化为 "[1,2,3,null,null,4,5]"
题源链接:https://leetcode-cn.com/problems/xu-lie-hua-er-cha-shu-lcof
/**
* 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:
// Encodes a tree to a single string.
string serialize(TreeNode* root) {
// 借助队列实现树的层次遍历
ostringstream out;
queue<TreeNode*> q;
// 将根节点加入队列
q.push(root);
while (!q.empty()) {
// 队列不为空,证明还有节点没有扫描完
TreeNode *currentNode = q.front(); // 获取队列的头
q.pop(); // 删除队列的头,应为这个节点已经扫描
if (currentNode) {
out << currentNode->val << " ";
// 将当前节点的左右节点入列(左右节点为空也要入列)
q.push(currentNode->left);
q.push(currentNode->right);
}
else {
out << "null ";
}
}
return out.str();
}
// Decodes your encoded data to tree.
TreeNode* deserialize(string data) {
// 字符串流解析
istringstream input(data);
string val;
vector<TreeNode*> vec;
while (input >> val) {
// 按空格拆解字符流,根据序列化的格式拆解
if (val == "null") {
vec.push_back(NULL);
}
else {
vec.push_back(new TreeNode(stoi(val)));
}
}
int j = 1; // i每往后移动一位,j移动两位,j始终是当前i的左子下标
for (int i = 0; j < vec.size(); ++i) { // 肯定是j先到达边界,所以这里判断j < vec.size()
if (vec[i] == NULL) continue; // vec[i]为null时跳过(节点为空不可能存在左右子节点)。
if (j < vec.size()) vec[i]->left = vec[j++]; // 当前j位置为i的左子树
if (j < vec.size()) vec[i]->right = vec[j++]; // 当前j位置为i的右子树
}
return vec[0]; // 返回根节点
}
};
// Your Codec object will be instantiated and called as such:
// Codec codec;
// codec.deserialize(codec.serialize(root));