总结:
二叉树的建立:可通过前序遍历和中序遍历创建一个二叉树
可通过中序遍历和后序遍历创建一个二叉树。
二叉树的序列化:前序遍历,或层序遍历均可。
二叉树的反序列化:前序遍历,或层序遍历均可,但要与序列化方法对应。
设计一个算法,并编写代码来序列化和反序列化二叉树。将树写入一个文件被称为“序列化”,读取文件后重建同样的二叉树被称为“反序列化”。
如何反序列化或序列化二叉树是没有限制的,你只需要确保可以将二叉树序列化为一个字符串,并且可以将字符串反序列化为原来的树结构。
样例
给出一个测试数据样例, 二叉树{3,9,20,#,#,15,7}
,表示如下的树结构:
3
/ \
9 20
/ \
15 7
我们的数据是进行BFS遍历得到的。当你测试结果wrong answer时,你可以作为输入调试你的代码。
你可以采用其他的方法进行序列化和反序列化。
这道题让我们对二叉树进行序列化和去序列化的操作。序列化就是将一个数据结构或物体转化为一个位序列,可以存进一个文件或者内存缓冲器中,然后通过网络连接在相同的或者另一个电脑环境中被还原,还原的过程叫做去序列化。现在让我们来序列化和去序列化一个二叉树,并给了我们例子。这题有两种解法,分别为先序遍历的递归解法和层序遍历的非递归解法。先来看先序遍历的递归解法,非常的简单易懂,我们需要接入输入和输出字符串流istringstream和ostringstream,对于序列化,我们从根节点开始,如果节点存在,则将值存入输出字符串流,然后分别对其左右子节点递归调用序列化函数即可。对于去序列化,我们先读入第一个字符,以此生成一个根节点,然后再对根节点的左右子节点递归调用去序列化函数即可,参见代码如下:
// Recursion
class Codec {
public:
// Encodes a tree to a single string.
string serialize(TreeNode* root) {
ostringstream out;
serialize(root, out);
return out.str();
}
// Decodes your encoded data to tree.
TreeNode* deserialize(string data) {
istringstream in(data);
return deserialize(in);
}
private:
void serialize(TreeNode *root, ostringstream &out) {
if (root) {
out << root->val << ' ';
serialize(root->left, out);
serialize(root->right, out);
} else {
out << "# ";
}
}
TreeNode* deserialize(istringstream &in) {
string val;
in >> val;
if (val == "#") return nullptr;
TreeNode *root = new TreeNode(stoi(val));
root->left = deserialize(in);
root->right = deserialize(in);
return root;
}
};
层序遍历:代码写的非常好
1、利用队列,先进先出的特性,对其进行层序遍历。
2、序列化方法要和反序列化方法相同,一个用层序遍历序列化,则要用层序遍历反序列化,否则肯定会出错。
string serialize(TreeNode* root)
{
string seq;
queue<TreeNode*> Q;
Q.push(root);
while(!Q.empty())
{
TreeNode* cur=Q.front();
Q.pop();
if(cur==NULL)
seq.push_back('#');
else
{
seq.push_back(cur->val);
Q.push(cur->left);
Q.push(cur->right);
}
}
return seq;
}
TreeNode* getNode(string& seq,int p)
{
if(seq[p]=='#')
return NULL;
else
{
return new TreeNode(seq[p]);
}
}
TreeNode* deserialize(string& seq)
{
if(seq.empty()||seq[0]=='#')
return NULL;
int p=0;
TreeNode* root=new TreeNode(seq[p++]);
queue<TreeNode*> Q;
Q.push(root);
while(!Q.empty())
{
TreeNode* cur=Q.front();
Q.pop();
cur->left=getNode(seq,p++);
cur->right=getNode(seq,p++);
if(cur->left)
Q.push(cur->left);
if(cur->right)
Q.push(cur->right);
}
return root;
}