序列化二叉树
题目
请实现两个函数,分别用来序列化和反序列化二叉树
二叉树的序列化是指:把一棵二叉树按照某种遍历方式的结果以某种格式保存为字符串,从而使得内存中建立起来的二叉树可以持久保存。序列化可以基于先序、中序、后序、层序的二叉树遍历方式来进行修改,序列化的结果是一个字符串,序列化时通过 某种符号表示空节点(#),以 ! 表示一个结点值的结束(value!)。
二叉树的反序列化是指:根据某种遍历顺序得到的序列化字符串结果str,重构二叉树。
思路
- 对于序列化:使用前序遍历,递归的将二叉树的值转化为字符,并且在每次二叉树的结点
不为空时,在转化val所得的字符之后添加一个’!'作为分割。对于空节点则以 ‘#’ 代替。 - 对于反序列化:按照前序顺序,递归的使用字符串中的字符创建一个二叉树(特别注意:
在递归时,递归函数的参数一定要是char ** ,这样才能保证每次递归后指向字符串的指针会
随着递归的进行而移动!!!)
实现
/*
1. 对于序列化:使用前序遍历,递归的将二叉树的值转化为字符,并且在每次二叉树的结点
不为空时,在转化val所得的字符之后添加一个'!'作为分割。对于空节点则以 '#' 代替。
2. 对于反序列化:按照前序顺序,递归的使用字符串中的字符创建一个二叉树(特别注意:
在递归时,递归函数的参数一定要是char ** ,这样才能保证每次递归后指向字符串的指针会
随着递归的进行而移动!!!)
*/
/*
struct TreeNode {
int val;
struct TreeNode *left;
struct TreeNode *right;
TreeNode(int x) :
val(x), left(NULL), right(NULL) {
}
};
*/
class Solution {
public:
char* Serialize(TreeNode *root) {
string str = "";
SerializeCore(root, str);
int len = str.size();
char *serial = new char[len+1];
for(int i=0; i<len; ++i)
{
serial[i] = str[i];
}
serial[len] = '\0';
return serial;
}
void SerializeCore(TreeNode *root, string & str)
{
if(root==nullptr){
str += '#';
return;
}
str = str + std::to_string(root->val) + '!';
SerializeCore(root->left, str);
SerializeCore(root->right, str);
}
TreeNode* Deserialize(char *str) {
int num;
TreeNode* root = nullptr;
DeserializeCore(&root, &str);
return root;
}
void DeserializeCore(TreeNode** root, char **str)
{
int num;
if(scanNumber(&(*str), num))
{
*root = new TreeNode(num);
DeserializeCore(&((*root)->left), &(*str));
DeserializeCore(&((*root)->right), &(*str));
}
}
bool scanNumber(char** str, int & num)
{
char *p = *str;
string val;
if(*p=='\0')
return false;
if(*p=='#'){
++p;
*str = p;
return false;
}
string numstr = "";
while(*p!='\0' && *p!='!'){
numstr+=*p;
++p;
}
if(*p=='!') ++p;
*str = p;
num = atoi(numstr.c_str());
return true;
}
};