原题网址: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},表示如下的树结构:

  1. 3
  2. / \
  3. 9 20
  4. / \
  5. 15 7

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

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

标签

 
思路:序列化二叉树时用广度优先搜素的方法,设置一个队列保存节点,依次遍历。因为空节点无法插入队列,所以用root代替空节点,这样判断当前节点是否为root就可以判断是有效节点还是空节点了。
注意,该程序结束时字符串尾部会插入多余的‘#’和‘,’,要将这些无效字符删掉。
 
更新:又测试了下发现NULL可以插入指针队列,emmm……
 
 
反序列化:依旧是利用队列的先入先出特性,因为要判断新建立的节点是左节点还是右节点,所以再设置一个bool类型的判断标志。
首先建立根节点,然后遍历字符串,如果当前字符为‘,’就continue;
如果为‘#’就判断新建立的是左节点还是右节点,如果是右节点代表其根节点已经全部挂载完成,此时需要队列出队,在下一个节点上继续挂载,同时标志反转;
否则,当前节点为有效数值,首先将这些字符转换成int型数据,然后new出一个二叉树节点,判断挂载在左侧还是右侧,然后标志反转,若是右侧,队列再出队。
 
 
AC代码:
注意空字符串要返回""而不是NULL……
以及,int转string可以用to_string(),但我测试代码时用的VS2010,还不能支持这个函数,所以自己定义了一个。
 
  1. /**
  2. * Definition of TreeNode:
  3. * class TreeNode {
  4. * public:
  5. * int val;
  6. * TreeNode *left, *right;
  7. * TreeNode(int val) {
  8. * this->val = val;
  9. * this->left = this->right = NULL;
  10. * }
  11. * }
  12. */
  13.  
  14. class Solution {
  15. public:
  16. /**
  17. * This method will be invoked first, you should design your own algorithm
  18. * to serialize a binary tree which denote by a root node to a string which
  19. * can be easily deserialized by your own "deserialize" method later.
  20. */
  21. string serialize(TreeNode * root) {
  22.  
  23. // write your code here
  24. if (root==NULL)
  25. {
  26. return "";//return NULL出错;
  27. }
  28. string result;
  29. //result=result+to_string(root->val);
  30. result=result+int2str(root->val);
  31.  
  32. queue<TreeNode *> level;
  33. level.push(root->left);
  34. level.push(root->right);
  35.  
  36. while(!level.empty())
  37. {
  38. TreeNode *temp=level.front();
  39. level.pop();
  40. if (temp!=NULL)
  41. {
  42. //result=result+","+to_string(temp->val);
  43. result=result+","+int2str(temp->val);
  44. level.push(temp->left);
  45. level.push(temp->right);
  46. }
  47. else
  48. {
  49. result=result+","+"#";
  50. }
  51. }
  52.  
  53. int size=result.size();
  54. int id=size-;
  55. while(id>&&(result[id]=='#'||result[id]==','))
  56. {
  57. id--;
  58. }
  59. result.resize(id+);
  60.  
  61. return result;
  62. }
  63.  
  64. /**
  65. * This method will be invoked second, the argument data is what exactly
  66. * you serialized at method "serialize", that means the data is not given by
  67. * system, it's given by your own serialize method. So the format of data is
  68. * designed by yourself, and deserialize it here as you serialize it in
  69. * "serialize" method.
  70. */
  71. TreeNode * deserialize(string &data) {
  72. // write your code here
  73. if (data.empty())
  74. {
  75. return NULL;
  76. }
  77.  
  78. int size=data.size();
  79. int i=;
  80. int ro=;//根节点数值;
  81. while(data[i]!=','&&i<size)
  82. {
  83. char tm=data[i];
  84. ro=ro*+tm-'';
  85. i++;
  86. }
  87. TreeNode * root=new TreeNode(ro);
  88.  
  89. queue<TreeNode *> level;
  90. TreeNode *index=root;
  91. bool isLeft=true;
  92.  
  93. for (;i<size;i++)
  94. {
  95. if (data[i]==',')
  96. {
  97. continue;
  98. }
  99. else if (data[i]=='#')
  100. {
  101. if (isLeft)
  102. {
  103. //index->left=NULL;
  104. isLeft=false;
  105. }
  106. else
  107. {
  108. //index->right=NULL;
  109. if (!level.empty())
  110. {
  111. index=level.front();
  112. level.pop();
  113. }
  114. isLeft=true;
  115. }
  116. }
  117. else
  118. {
  119. int val=;
  120. while(i<size&&data[i]!=',') //注意不能写成data[i]!=','&&i<size,因为下标可能超出范围;
  121. {
  122. char temp=data[i];
  123. val=val*+temp-'';
  124. i++;
  125. }
  126.  
  127. TreeNode * tempNode=new TreeNode(val);
  128. level.push(tempNode);
  129. if (isLeft)
  130. {
  131. index->left=tempNode;
  132. isLeft=false;
  133. }
  134. else
  135. {
  136. index->right=tempNode;
  137. if (!level.empty())
  138. {
  139. index=level.front();
  140. level.pop();
  141. }
  142. isLeft=true;
  143. }
  144. }
  145. }
  146. return root;
  147. }
  148.  
  149. string int2str(int &i)
  150. {
  151. string str;
  152. stringstream stream;
  153. stream<<i;
  154. str=stream.str();//stream>>str;
  155. return str;
  156. }
  157.  
  158. };
 
 原来的代码……留个纪念。
  1. /**
  2. * Definition of TreeNode:
  3. * class TreeNode {
  4. * public:
  5. * int val;
  6. * TreeNode *left, *right;
  7. * TreeNode(int val) {
  8. * this->val = val;
  9. * this->left = this->right = NULL;
  10. * }
  11. * }
  12. */
  13.  
  14. class Solution {
  15. public:
  16. /**
  17. * This method will be invoked first, you should design your own algorithm
  18. * to serialize a binary tree which denote by a root node to a string which
  19. * can be easily deserialized by your own "deserialize" method later.
  20. */
  21. string serialize(TreeNode * root) {
  22.  
  23. // write your code here
  24. if (root==NULL)
  25. {
  26. return "";
  27. }
  28. string result;
  29. //result=result+to_string(root->val);
  30. result=result+int2str(root->val);
  31.  
  32. queue<TreeNode *> level;
  33. if (root->left==NULL&&root->right!=NULL)
  34. {
  35. level.push(root);
  36. level.push(root->right);
  37. }
  38. else if (root->left!=NULL&&root->right==NULL)
  39. {
  40. level.push(root->left);
  41. level.push(root);
  42. }
  43. else if (root->left!=NULL&&root->right!=NULL)
  44. {
  45. level.push(root->left);
  46. level.push(root->right);
  47. }
  48.  
  49. while(!level.empty())
  50. {
  51. TreeNode *temp=level.front();
  52. level.pop();
  53. if (temp!=root)
  54. {
  55. //result=result+","+to_string(temp->val);
  56. result=result+","+int2str(temp->val);
  57.  
  58. if (temp->left!=NULL&&temp->right!=NULL)
  59. {
  60. level.push(temp->left);
  61. level.push(temp->right);
  62. }
  63. else if (temp->left==NULL&&temp->right!=NULL)
  64. {
  65. level.push(root);
  66. level.push(temp->right);
  67. }
  68. else if (temp->left!=NULL&&temp->right==NULL)
  69. {
  70. level.push(temp->left);
  71. level.push(root);
  72. }
  73. else
  74. {
  75. level.push(root);
  76. level.push(root);
  77. }
  78. }
  79. else
  80. {
  81. result=result+","+"#";
  82. }
  83. }
  84.  
  85. int size=result.size();
  86. int id=size-;
  87. while(id>&&(result[id]=='#'||result[id]==','))
  88. {
  89. id--;
  90. }
  91. result.resize(id+);
  92.  
  93. return result;
  94. }
  95.  
  96. /**
  97. * This method will be invoked second, the argument data is what exactly
  98. * you serialized at method "serialize", that means the data is not given by
  99. * system, it's given by your own serialize method. So the format of data is
  100. * designed by yourself, and deserialize it here as you serialize it in
  101. * "serialize" method.
  102. */
  103. TreeNode * deserialize(string &data) {
  104. // write your code here
  105. if (data.empty())
  106. {
  107. return NULL;
  108. }
  109.  
  110. int size=data.size();
  111. int i=;
  112. int ro=;//根节点数值;
  113. while(data[i]!=','&&i<size)
  114. {
  115. char tm=data[i];
  116. ro=ro*+tm-'';
  117. i++;
  118. }
  119. TreeNode * root=new TreeNode(ro);
  120.  
  121. queue<TreeNode *> level;
  122. TreeNode *index=root;
  123. bool isLeft=true;
  124.  
  125. for (;i<size;i++)
  126. {
  127. if (data[i]==',')
  128. {
  129. continue;
  130. }
  131. else if (data[i]=='#')
  132. {
  133. if (isLeft)
  134. {
  135. //index->left=NULL;
  136. isLeft=false;
  137. }
  138. else
  139. {
  140. //index->right=NULL;
  141. if (!level.empty())
  142. {
  143. index=level.front();
  144. level.pop();
  145. }
  146. isLeft=true;
  147. }
  148. }
  149. else
  150. {
  151. int val=;
  152. while(i<size&&data[i]!=',') //注意不能写成data[i]!=','&&i<size,因为下标可能超出范围;
  153. {
  154. char temp=data[i];
  155. val=val*+temp-'';
  156. i++;
  157. }
  158.  
  159. TreeNode * tempNode=new TreeNode(val);
  160. level.push(tempNode);
  161. if (isLeft)
  162. {
  163. index->left=tempNode;
  164. isLeft=false;
  165. }
  166. else
  167. {
  168. index->right=tempNode;
  169. if (!level.empty())
  170. {
  171. index=level.front();
  172. level.pop();
  173. }
  174. isLeft=true;
  175. }
  176. }
  177. }
  178. return root;
  179. }
  180.  
  181. string int2str(int &i)
  182. {
  183. string str;
  184. stringstream stream;
  185. stream<<i;
  186. str=stream.str();//stream>>str;
  187. return str;
  188. }
  189.  
  190. };

参考: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. 5.1_springboot2.x与安全(spring security)

    1.简介 常见的两个安全框架shiro|spring security,这里只介绍spring security; Spring Security是针对Spring项目的安全框架,也是Spring B ...

  2. bias、variance与拟合之间的关系

    Error = Bias^2 + Variance+Noise 误差的原因: 1.Bias反映的是模型在样本上的输出与真实值之间的误差,即模型本身的精准度,即算法本身的拟合能力. 2.Variance ...

  3. Ip HostName查询

    https://iplist.cc/api // 在线ip hostname查询

  4. vue3环境搭建以及创建简单项目。

    1.环境准备,以下都是我的版本.自己在官网上面下载需要的版本. 尝试了Python3.7.3在创建vue3项目时出现问题. node.js10.16.0, python2.7.16, yarn1.16 ...

  5. java运行字符串代码

    本文链接:https://blog.csdn.net/junlong750/article/details/50945883

  6. 家庭-养老院模型理解IOC和DI

    控制反转 IOC 1. 概念 应用内部不负责依赖对象的创建和维护, 由第三方负责, 这样控制权就由应用内部转移到外部容器, 控制权的转移就是所谓的反转. 2. 比喻 有一户家庭(应用)有个老人(依赖对 ...

  7. leetcode-90-子集②

    题目描述: 方法一:回溯 class Solution: def subsetsWithDup(self, nums: List[int]) -> List[List[int]]: nums.s ...

  8. duilib库分析1.消息流程分析

    看下CWindowWnd类与CPaintManagerUI类是咋进行消息分发的吧. 1. 先看下CPaintManagerUI类的MessageLoop函数: void CPaintManagerUI ...

  9. SpringCloud学习笔记(九):SpringCloud Config 分布式配置中心

    概述 分布式系统面临的-配置问题 微服务意味着要将单体应用中的业务拆分成一个个子服务,每个服务的粒度相对较小,因此系统中会出现大量的服务.由于每个服务都需要必要的配置信息才能运行,所以一套集中式的.动 ...

  10. 十条服务器端优化Web性能的技巧总结

    原文地址:http://www.jb51.net/yunying/452723.html 提高 web 应用的性能从来没有比现在更重要过.网络经济的比重一直在增长:全球经济超过 5% 的价值是在因特网 ...