一.题意整理
请实现两个函数,分别用来序列化和反序列化二叉树。
1.二叉树的序列化是指:
把一棵二叉树按照某种遍历方式的结果以某种格式保存为字符串,从而使得内存中建立起来的二叉树可以持久保存。序列化可以基于先序、中序、后序、层序的二叉树遍历方式来进行修改,序列化的结果是一个字符串,序列化时通过 某种符号表示空节点,以某个符号表示一个结点值的结束。
2.二叉树的反序列化是指:
根据某种遍历顺序得到的序列化字符串结果str,重构二叉树。
二.思路整理
序列化:
按照层次遍历将每个节点加入字符串中,当遇到空节点则加入null。
反序列化:
同样按照层次遍历的思想,首先构造头节点,然后再遍历节点的同时构造其左右子节点并入队列,当队列为空时,反序列化完毕。
题目对于遍历后的序列没有太大的要求,所以我们可以任意采用遍历方式。这里我们使用先序遍历的方式序列化二叉树,用' # '表示空,' * ' 标志一个结点值的结束,序列化时通过先序遍历的顺序,当遇到非空节点时取出其值的字符串表示再在后面加个'!'标示着结尾,以便我们反序列化时确定节点的值出于代码编写的遍历,我们先用string记录得到序列,再利用c_str()转换为题目要求的 char* 字符串。
三.代码实现
class Solution {
public:
//先序遍历利用string记录先序序列
void inorder(TreeNode *root,string& s){
if(root==nullptr){
s+="#";
return;
}
s+=to_string(root->val)+"*";
inorder(root->left,s);
inorder(root->right,s);
}
//返回先序遍历的字符串
char* Serialize(TreeNode *root) {
string s;
inorder(root,s);
char* ans = new char[105];
strcpy(ans,s.c_str());
return ans;
}
TreeNode* deserialize(char *s, int& cnt){
if(s[cnt]=='#'){
cnt++;
return nullptr;
}
//判断是否是负数
bool ck=1;
if(s[cnt]=='-'){
ck=0;
cnt++;
}
int num=0;
//对字符串中的数进行提取
while(s[cnt]!='*'){
num=num*10+s[cnt]-'0';
cnt++;
}
if(!ck) num-=num;
cnt++;
TreeNode* root = new TreeNode(num);
//递归
root->left = deserialize(s,cnt);
root->right = deserialize(s,cnt);
return root;
}
TreeNode* Deserialize(char *str) {
int now=0;
//返回反序列化的值
return deserialize(str,now);
}
};