思路:通过前序、后续、或者层次遍历二叉树,用一个字符串保存节点的值,要注意的是,每个节点的值之后要添加一个特殊符号(比如下划线)分隔,否则可能无法区分节点的值。
比如一个节点的值可能是12,不加下划线的话,反序列化时就分不清楚,12表示的是一个值为12的节点,或者两个节点,其值分别为1,2。
split函数用来去除原来作为分割的符号,本文中用来去除下划线。
总之:怎么序列化二叉树就怎么反序列化二叉树。
还要注意节点值为负号的情况,为了正确识别序列化后字符串中的负号,split中用来保存结果的容器可以选用vector<int>.
下面给出两种方法:
方法一:按层次遍历的顺序序列化和反序列化
class Codec {//按层序列化
private:
void split(const string &src,vector<int>& vec,const char& delimiter){
vec.clear();
istringstream iss(src);
string tmp;
while(getline(iss,tmp,delimiter)){
if(tmp!="#")
vec.push_back(stoi(tmp));//注意转换成int
else
vec.push_back(0x3f3f3f3f);//tmp为“#”时,推入一个特殊的数
}
}
public:
// Encodes a tree to a single string.
string serialize(TreeNode* root) {
if(root==NULL)
return "";
string str;
queue<TreeNode* >q;
q.push(root);
str+=to_string(root->val)+'_';//不要忘了记录头结点的值
while(!q.empty()){
TreeNode* cur=q.front();
q.pop();
if(cur->left) {
q.push(cur->left);
str+=to_string(cur->left->val)+"_";
}else{//没有左孩子时
str+="#_";
}
if(cur->right) {
q.push(cur->right);
str+=to_string(cur->right->val)+"_";
}else{
str+="#_";
}
}
return str;
}
// Decodes your encoded data to tree.
TreeNode* deserialize(string data) {
if(data.empty())
return NULL;
vector<int> vec;//用来保存
split(data,vec,'_');//以下划线做分割符
size_t pos=0;
TreeNode* newRoot=new TreeNode(vec[pos++]);//生成一个新的头结点
queue<TreeNode*> q;
q.push(newRoot);
TreeNode* cur=NULL;
while(!q.empty()){
cur=q.front();
q.pop();
cur->left=(vec[pos]==0x3f3f3f3f)?NULL:new TreeNode(vec[pos]);
++pos;
cur->right=(vec[pos]==0x3f3f3f3f)?NULL:new TreeNode(vec[pos]);
++pos;
if(cur->left)
q.push(cur->left);
if(cur->right)
q.push(cur->right);
}
return newRoot;
}
};
方法二:按照前序遍历的方法序列化和反序列化
class Codec {//按照前序遍历来序列化
private:
void _serialize(TreeNode* cur,string &s){
if(cur==NULL){
s+="#_";
return ;
}
s+=to_string(cur->val)+"_";
_serialize(cur->left,s);
_serialize(cur->right,s);
return;
}
void split(const string& src,vector<int>& vec,const char delimiter){//不要用string去接收结果
vec.clear();//若用string,则处理负号比较麻烦
istringstream iss(src);
string tmp;
while(getline(iss,tmp,delimiter)){
if(tmp=="#")
vec.push_back(0x3f3f3f3f);//注意这里的特殊处理
else
vec.push_back(stoi(tmp));
}
}
TreeNode* _deserialize(const vector<int>& data,int &idx){
if(data.empty()||idx>=data.size()||data[idx]==0x3f3f3f3f)
return NULL;
TreeNode* cur=new TreeNode(data[idx]);
cur->left=_deserialize(data,++idx);
cur->right=_deserialize(data,++idx);
return cur;
}
public:
// Encodes a tree to a single string.
string serialize(TreeNode* root) {
if(root==NULL)
return "";
string s;
_serialize(root,s);
return s;
}
// Decodes your encoded data to tree.
TreeNode* deserialize(string data) {
if(data.empty())
return NULL;
vector<int> res;
split(data,res,'_');
int pos=0;
TreeNode *newHead=_deserialize(res,pos);
return newHead;
}
};