题目描述
请实现两个函数,分别用来序列化和反序列化二叉树
二叉树的序列化是指:把一棵二叉树按照某种遍历方式的结果以某种格式保存为字符串,从而使得内存中建立起来的二叉树可以持久保存。序列化可以基于先序、中序、后序、层序的二叉树遍历方式来进行修改,序列化的结果是一个字符串,序列化时通过 某种符号表示空节点(#),以 ! 表示一个结点值的结束(value!)。
二叉树的反序列化是指:根据某种遍历顺序得到的序列化字符串结果str,重构二叉树。
例如,我们可以把一个只有根节点为1的二叉树序列化为"1,",然后通过自己的函数来解析回这个二叉树
考察点:复杂问题分解;递归求子问题。
思路:参考了大佬的一些想法,这个序列化的时候返回字符串数组有点坑,所以先递归转化为字符串。其他见注释。
struct TreeNode {
int val;
struct TreeNode* left;
struct TreeNode* right;
TreeNode(int x) :
val(x), left(NULL), right(NULL) {
}
};
class Solution {
public:
void Serialize(TreeNode* root, string& str)//将树序列化为字符串
{
if (root == NULL)
{
str += '#';//树根为空,加特殊字符
return;
}
string r = to_string(root->val);//将根节点的值转为字符串
str += r;
str += '!';//单个数值结束的标志
Serialize(root->left, str);
Serialize(root->right,str);
}
char* Serialize(TreeNode* root) {
if (root == NULL)
return NULL;
string str;
Serialize(root, str);//得到字符串序列
char* result = new char[str.length() + 1];//从字符串中复制元素到字符数组
for (int i = 0; i < str.length(); i++)
{
result[i] = str[i];
}
result[str.length()] = '\0';
return result;//返回字符数组
}
TreeNode* tDeserialize(char*& str)//不断的向后读取字符串,这里用指针的引用改变指针。代替二级指针。
{
if (*str == '#') //空子树
{
str++;
return NULL;//树的节点为空
}
int sum = 0;//计算出当前数值
while (*str != '\0' && *str != '!')//没到结尾,或者没到数值结束标识
{
sum = sum * 10 + *str - '0';
str++;
}
TreeNode* root = new TreeNode(sum);//构建新节点
if (*str == '\0')
{
return root;//到达结尾,返回根节点
}
else //到达!继续前行
str++;
//按照先序遍历继续递归。
root->left = tDeserialize(str);//构造左子树
root->right = tDeserialize(str);//构造右子树
return root;
}
TreeNode* Deserialize(char* str)
{
if (str == NULL) //到达字符数组结尾
return NULL;
TreeNode* root = tDeserialize(str);
return root;
}
};