原题网址:http://www.lintcode.com/zh-cn/problem/serialize-and-deserialize-binary-tree/#

设计一个算法,并编写代码来序列化和反序列化二叉树。将树写入一个文件被称为“序列化”,读取文件后重建同样的二叉树被称为“反序列化”。

如何反序列化或序列化二叉树是没有限制的,你只需要确保可以将二叉树序列化为一个字符串,并且可以将字符串反序列化为原来的树结构。

注意事项

There is no limit of how you deserialize or serialize a binary tree, LintCode will take your output of serialize as the input of deserialize, it won't check the result of serialize.

您在真实的面试中是否遇到过这个题?

Yes
样例

给出一个测试数据样例, 二叉树{3,9,20,#,#,15,7},表示如下的树结构:

  3
/ \
9 20
/ \
15 7

我们的数据是进行BFS遍历得到的。当你测试结果wrong answer时,你可以作为输入调试你的代码。

你可以采用其他的方法进行序列化和反序列化。

标签

 
思路:序列化二叉树时用广度优先搜素的方法,设置一个队列保存节点,依次遍历。因为空节点无法插入队列,所以用root代替空节点,这样判断当前节点是否为root就可以判断是有效节点还是空节点了。
注意,该程序结束时字符串尾部会插入多余的‘#’和‘,’,要将这些无效字符删掉。
 
更新:又测试了下发现NULL可以插入指针队列,emmm……
 
 
反序列化:依旧是利用队列的先入先出特性,因为要判断新建立的节点是左节点还是右节点,所以再设置一个bool类型的判断标志。
首先建立根节点,然后遍历字符串,如果当前字符为‘,’就continue;
如果为‘#’就判断新建立的是左节点还是右节点,如果是右节点代表其根节点已经全部挂载完成,此时需要队列出队,在下一个节点上继续挂载,同时标志反转;
否则,当前节点为有效数值,首先将这些字符转换成int型数据,然后new出一个二叉树节点,判断挂载在左侧还是右侧,然后标志反转,若是右侧,队列再出队。
 
 
AC代码:
注意空字符串要返回""而不是NULL……
以及,int转string可以用to_string(),但我测试代码时用的VS2010,还不能支持这个函数,所以自己定义了一个。
 
/**
* Definition of TreeNode:
* class TreeNode {
* public:
* int val;
* TreeNode *left, *right;
* TreeNode(int val) {
* this->val = val;
* this->left = this->right = NULL;
* }
* }
*/ class Solution {
public:
/**
* This method will be invoked first, you should design your own algorithm
* to serialize a binary tree which denote by a root node to a string which
* can be easily deserialized by your own "deserialize" method later.
*/
string serialize(TreeNode * root) { // write your code here
if (root==NULL)
{
return "";//return NULL出错;
}
string result;
//result=result+to_string(root->val);
result=result+int2str(root->val); queue<TreeNode *> level;
level.push(root->left);
level.push(root->right); while(!level.empty())
{
TreeNode *temp=level.front();
level.pop();
if (temp!=NULL)
{
//result=result+","+to_string(temp->val);
result=result+","+int2str(temp->val);
level.push(temp->left);
level.push(temp->right);
}
else
{
result=result+","+"#";
}
} int size=result.size();
int id=size-;
while(id>&&(result[id]=='#'||result[id]==','))
{
id--;
}
result.resize(id+); return result;
} /**
* This method will be invoked second, the argument data is what exactly
* you serialized at method "serialize", that means the data is not given by
* system, it's given by your own serialize method. So the format of data is
* designed by yourself, and deserialize it here as you serialize it in
* "serialize" method.
*/
TreeNode * deserialize(string &data) {
// write your code here
if (data.empty())
{
return NULL;
} int size=data.size();
int i=;
int ro=;//根节点数值;
while(data[i]!=','&&i<size)
{
char tm=data[i];
ro=ro*+tm-'';
i++;
}
TreeNode * root=new TreeNode(ro); queue<TreeNode *> level;
TreeNode *index=root;
bool isLeft=true; for (;i<size;i++)
{
if (data[i]==',')
{
continue;
}
else if (data[i]=='#')
{
if (isLeft)
{
//index->left=NULL;
isLeft=false;
}
else
{
//index->right=NULL;
if (!level.empty())
{
index=level.front();
level.pop();
}
isLeft=true;
}
}
else
{
int val=;
while(i<size&&data[i]!=',') //注意不能写成data[i]!=','&&i<size,因为下标可能超出范围;
{
char temp=data[i];
val=val*+temp-'';
i++;
} TreeNode * tempNode=new TreeNode(val);
level.push(tempNode);
if (isLeft)
{
index->left=tempNode;
isLeft=false;
}
else
{
index->right=tempNode;
if (!level.empty())
{
index=level.front();
level.pop();
}
isLeft=true;
}
}
}
return root;
} string int2str(int &i)
{
string str;
stringstream stream;
stream<<i;
str=stream.str();//stream>>str;
return str;
} };
 
 原来的代码……留个纪念。
/**
* Definition of TreeNode:
* class TreeNode {
* public:
* int val;
* TreeNode *left, *right;
* TreeNode(int val) {
* this->val = val;
* this->left = this->right = NULL;
* }
* }
*/ class Solution {
public:
/**
* This method will be invoked first, you should design your own algorithm
* to serialize a binary tree which denote by a root node to a string which
* can be easily deserialized by your own "deserialize" method later.
*/
string serialize(TreeNode * root) { // write your code here
if (root==NULL)
{
return "";
}
string result;
//result=result+to_string(root->val);
result=result+int2str(root->val); queue<TreeNode *> level;
if (root->left==NULL&&root->right!=NULL)
{
level.push(root);
level.push(root->right);
}
else if (root->left!=NULL&&root->right==NULL)
{
level.push(root->left);
level.push(root);
}
else if (root->left!=NULL&&root->right!=NULL)
{
level.push(root->left);
level.push(root->right);
} while(!level.empty())
{
TreeNode *temp=level.front();
level.pop();
if (temp!=root)
{
//result=result+","+to_string(temp->val);
result=result+","+int2str(temp->val); if (temp->left!=NULL&&temp->right!=NULL)
{
level.push(temp->left);
level.push(temp->right);
}
else if (temp->left==NULL&&temp->right!=NULL)
{
level.push(root);
level.push(temp->right);
}
else if (temp->left!=NULL&&temp->right==NULL)
{
level.push(temp->left);
level.push(root);
}
else
{
level.push(root);
level.push(root);
}
}
else
{
result=result+","+"#";
}
} int size=result.size();
int id=size-;
while(id>&&(result[id]=='#'||result[id]==','))
{
id--;
}
result.resize(id+); return result;
} /**
* This method will be invoked second, the argument data is what exactly
* you serialized at method "serialize", that means the data is not given by
* system, it's given by your own serialize method. So the format of data is
* designed by yourself, and deserialize it here as you serialize it in
* "serialize" method.
*/
TreeNode * deserialize(string &data) {
// write your code here
if (data.empty())
{
return NULL;
} int size=data.size();
int i=;
int ro=;//根节点数值;
while(data[i]!=','&&i<size)
{
char tm=data[i];
ro=ro*+tm-'';
i++;
}
TreeNode * root=new TreeNode(ro); queue<TreeNode *> level;
TreeNode *index=root;
bool isLeft=true; for (;i<size;i++)
{
if (data[i]==',')
{
continue;
}
else if (data[i]=='#')
{
if (isLeft)
{
//index->left=NULL;
isLeft=false;
}
else
{
//index->right=NULL;
if (!level.empty())
{
index=level.front();
level.pop();
}
isLeft=true;
}
}
else
{
int val=;
while(i<size&&data[i]!=',') //注意不能写成data[i]!=','&&i<size,因为下标可能超出范围;
{
char temp=data[i];
val=val*+temp-'';
i++;
} TreeNode * tempNode=new TreeNode(val);
level.push(tempNode);
if (isLeft)
{
index->left=tempNode;
isLeft=false;
}
else
{
index->right=tempNode;
if (!level.empty())
{
index=level.front();
level.pop();
}
isLeft=true;
}
}
}
return root;
} string int2str(int &i)
{
string str;
stringstream stream;
stream<<i;
str=stream.str();//stream>>str;
return str;
} };

参考:C++中int、string等常见类型转换

C++中int与string的相互转换

C++ STL--queue 的使用方法

其他参考:
 
 
 

7 Serialize and Deserialize Binary Tree 序列化及反序列化二叉树的更多相关文章

  1. [leetcode]297. Serialize and Deserialize Binary Tree 序列化与反序列化二叉树

    Serialization is the process of converting a data structure or object into a sequence of bits so tha ...

  2. [leetcode]428. Serialize and Deserialize N-ary Tree序列化与反序列化N叉树

    Serialization is the process of converting a data structure or object into a sequence of bits so tha ...

  3. [LintCode] Serialize and Deserialize Binary Tree(二叉树的序列化和反序列化)

    描述 设计一个算法,并编写代码来序列化和反序列化二叉树.将树写入一个文件被称为“序列化”,读取文件后重建同样的二叉树被称为“反序列化”. 如何反序列化或序列化二叉树是没有限制的,你只需要确保可以将二叉 ...

  4. 【LeetCode】297. Serialize and Deserialize Binary Tree 解题报告(Python)

    [LeetCode]297. Serialize and Deserialize Binary Tree 解题报告(Python) 标签: LeetCode 题目地址:https://leetcode ...

  5. [LeetCode] Serialize and Deserialize Binary Tree

    Serialize and Deserialize Binary Tree Serialization is the process of converting a data structure or ...

  6. LC 297 Serialize and Deserialize Binary Tree

    问题: Serialize and Deserialize Binary Tree 描述: Serialization is the process of converting a data stru ...

  7. LeetCode——Serialize and Deserialize Binary Tree

    Description: Serialization is the process of converting a data structure or object into a sequence o ...

  8. LintCode 7.Serialize and Deserialize Binary Tree(含测试代码)

    题目描述 设计一个算法,并编写代码来序列化和反序列化二叉树.将树写入一个文件被称为“序列化”,读取文件后重建同样的二叉树被称为“反序列化”. 如何反序列化或序列化二叉树是没有限制的,你只需要确保可以将 ...

  9. [LeetCode] Serialize and Deserialize Binary Tree 二叉树的序列化和去序列化

    Serialization is the process of converting a data structure or object into a sequence of bits so tha ...

随机推荐

  1. 18-MySQL-Ubuntu-数据表的查询-连接(七)

    students与classes表,两个表的连接字段是students.cls_id=classes.ID (1) 左连接:left join on 左边表全取,右边表取共有的,没有的为null se ...

  2. Reverses CodeForces - 906E (最小回文分解)

    题意: 给你两个串s和t,其中t是由s中选择若干个不相交的区间翻转得到的,现在要求求出最少的翻转次数以及给出方案. 1≤|s|=|t|≤500000 题解: 我们将两个字符串合成成T=s1t1s2t2 ...

  3. java锁分析

    import java.util.concurrent.TimeUnit; class Phone//Phone.java ---> Phone.class Class.forName(); { ...

  4. sql(7)

    EXCEPT是指在第一个集合中存在,但是不存在于第二个集合中的数据. EXCEPT 子句/运算符用于将两个 SELECT 语句结合在一起,并返回第一个 SELECT 语句的结果中那些不存在于第二个 S ...

  5. Android开发 AAC的ADTS头解析[转载]

    原文地址:https://www.jianshu.com/p/b5ca697535bd 1. ADTS(Audio Data Transport Stream)头之于AAC AAC音频文件的每一帧都由 ...

  6. [转]springmvc+mybatis需要的jar包与详解

    1.antlr-2.7.6.jar:  项目中没有添加,hibernate不会执行hql语句 2.Aopalliance.jar: 这个包是AOP联盟的API包,里面包含了针对面向切面的接口,通常Sp ...

  7. 【JZOJ6273】欠钱

    description analysis 读懂题就可知\(b\)的收益即为\(a\)到\(b\)这一条链上边权的最小值 那么就是动态维护一个森林,询问链上最小值,同时必须满足儿子走向父亲 明显\(LC ...

  8. PouchContainer 开源版本及内部版本一致性实践

    PouchContainer 开源版本及内部版本一致性实践 为什么要做内外版本一致 对外开源是提升影响力.共建生态的有力手段.在项目对外开源的过程中,首先是将可以开源的部分抽离出来,发布一个“开源版本 ...

  9. eclipse配置外部工具利用javah编译生成头文件

    1. 点击eclipse工具栏外部工具按钮,打开配置外部工具 2. 新建一个启动配置,起名为Generate C and C++ Header File,按照下图配置好相应的参数 3. 运行该工具时, ...

  10. python的起源及基本语句

    一.Python的起源 Python是吉多范罗苏姆于1989年的圣诞节期间在阿姆斯特丹进行编写的,于1991年编写完成,Python是一门解释型弱类型的编程语言. Python在多个领域中都有应用,比 ...