题目

请实现两个函数,分别用来序列化和反序列化二叉树。

分析

我们清楚可以通过前序遍历序列和中序遍历序列创造出一棵二叉树。因此,我们可以先把一棵二叉树序列化成一个前序遍历序列和一个中序遍历序列,然后在反序列化时通过这两种序列还原二叉树。

但是,该方法有两个缺点:

  1. 该方法要求二叉树中不能有数值重复的节点
  2. 只有当两个序列中所有数据读出来才能开始序列化。如果两个遍历序列的数据是从一个流里读出来的,那么可能需要等待较长时间。

实际上,如果二叉树的序列化是从根节点开始的,那么相应的反序列化在根节点的数值读出来的时候就可以开始了。因此,我们可以根据前序遍历的顺序来序列化二叉树,因为前序遍历是从根节点开始的。在遍历二叉树碰到空指针时,这些空指针序列化为一个特殊的字符(如$)。另外,节点的数值之间要用一个特殊字符 (如,) 隔开。

反序列化二叉树也按照前序遍历思路。

放码

import com.lun.util.BinaryTree.TreeNode;public class SerializeBinaryTree {public void serialize(TreeNode node, StringBuilder result) {if(node == null) {result.append("$,");return;}result.append(node.val + ",");serialize(node.left, result);serialize(node.right, result);}public TreeNode deserialize(StringBuilder sb) {Integer number = readNum(sb);TreeNode node = null;if(number != null) {node = new TreeNode(number);node.left = deserialize(sb);node.right = deserialize(sb);}return node;}public Integer readNum(StringBuilder sb) {int firstCommaIndex = sb.indexOf(",");String numStr = sb.substring(0, firstCommaIndex);Integer result = null;if(!numStr.equals("$")) {result = Integer.valueOf(numStr);}try {sb.delete(0, firstCommaIndex + 1);}catch (Exception e) {// do nothing}return result;}}

测试

import static org.junit.Assert.*;import org.junit.Test;import com.lun.util.BinaryTree;
import com.lun.util.BinaryTree.TreeNode;public class SerializeBinaryTreeTest {@Testpublic void testSerialize() {SerializeBinaryTree sbt = new SerializeBinaryTree();StringBuilder result = new StringBuilder("");TreeNode root = makeATree();sbt.serialize(root, result);assertEquals("1,2,4,$,$,$,3,5,$,$,6,$,$,", result.toString());}@Testpublic void testReadNum() {SerializeBinaryTree sbt = new SerializeBinaryTree();StringBuilder sb = new StringBuilder("1,2,4,$,$,$,3,5,$,$,6,$,$,");assertEquals(1, sbt.readNum(sb).intValue());assertEquals("2,4,$,$,$,3,5,$,$,6,$,$,", sb.toString());assertEquals(2, sbt.readNum(sb).intValue());assertEquals("4,$,$,$,3,5,$,$,6,$,$,", sb.toString());assertEquals(4, sbt.readNum(sb).intValue());assertEquals("$,$,$,3,5,$,$,6,$,$,", sb.toString());assertNull(sbt.readNum(sb));assertEquals("$,$,3,5,$,$,6,$,$,", sb.toString());assertNull(sbt.readNum(sb));assertEquals("$,3,5,$,$,6,$,$,", sb.toString());assertNull(sbt.readNum(sb));assertEquals("3,5,$,$,6,$,$,", sb.toString());assertEquals(3, sbt.readNum(sb).intValue());assertEquals("5,$,$,6,$,$,", sb.toString());assertEquals(5, sbt.readNum(sb).intValue());assertEquals("$,$,6,$,$,", sb.toString());assertNull(sbt.readNum(sb));assertEquals("$,6,$,$,", sb.toString());assertNull(sbt.readNum(sb));assertEquals("6,$,$,", sb.toString());assertEquals(6, sbt.readNum(sb).intValue());assertEquals("$,$,", sb.toString());assertNull(sbt.readNum(sb));assertEquals("$,", sb.toString());assertNull(sbt.readNum(sb));assertEquals("", sb.toString());}@Testpublic void testDeserialize() {SerializeBinaryTree sbt = new SerializeBinaryTree();TreeNode root = null;TreeNode root2 = makeATree();StringBuilder sb = new StringBuilder("");sbt.serialize(root2, sb);root = sbt.deserialize(sb);assertTrue(BinaryTree.equals(root, root2));}private TreeNode makeATree() {TreeNode root = new TreeNode(1);root.left = new TreeNode(2);root.right = new TreeNode(3);root.left.left = new TreeNode(4);root.right.left = new TreeNode(5);root.right.right = new TreeNode(6);return root;}}

《剑指Offer》37:序列化二叉树相关推荐

  1. 【LeetCode】剑指 Offer 37. 序列化二叉树

    [LeetCode]剑指 Offer 37. 序列化二叉树 文章目录 [LeetCode]剑指 Offer 37. 序列化二叉树 package offer;import java.util.Link ...

  2. 剑指 Offer 37. 序列化二叉树

    题目 序列化是将一个数据结构或者对象转换为连续的比特位的操作,进而可以将转换后的数据存储在一个文件或者内存中,同时也可以通过网络传输到另一个计算机环境,采取相反方式重构得到原数据. 请设计一个算法来实 ...

  3. 【LeetCode笔记】剑指Offer 37. 序列化二叉树(Java、二叉树、序列化、BFS、队列)

    文章目录 题目描述 思路 && 代码 二刷 题目描述 这道题涉及到不少 String.StringBuilder.Integer的转换.处理. 思路 && 代码 序列化 ...

  4. 《剑指offer》-- 序列化二叉树、二叉搜索树的第k个节点、数据流中的中位数、滑动窗口的最大值

    一.序列化二叉树: 1.题目: 请实现两个函数,分别用来序列化和反序列化二叉树. 2.解题思路: (1)根据前序遍历规则完成序列化与反序列化.所谓序列化指的是遍历二叉树为字符串:所谓反序列化指的是依据 ...

  5. 35-剑指 Offer 37. 序列化二叉树

    题目 请实现两个函数,分别用来序列化和反序列化二叉树. 你需要设计一个算法来实现二叉树的序列化与反序列化.这里不限定你的序列 / 反序列化算法执行逻辑,你只需要保证一个二叉树可以被序列化为一个字符串并 ...

  6. 《剑指offer》序列化二叉树

    题目:请实现两个函数,分别用来序列化和反序列化二叉树 解析:首先存储二叉树的先序遍历,遇到null就添加"#," 否则添加"值,".构件二叉树的时候也是用先序遍 ...

  7. [剑指offer] 61. 序列化二叉树

    题目描述 请实现两个函数,分别用来序列化和反序列化二叉树 题目很差,没有测试样例. 默认是先序遍历序列化. class Solution {public:vector<int> vec;v ...

  8. 【LeetCode】剑指 Offer 07. 重建二叉树

    [LeetCode]剑指 Offer 07. 重建二叉树 文章目录 [LeetCode]剑指 Offer 07. 重建二叉树 package offer;import java.util.ArrayD ...

  9. 【LeetCode】剑指 Offer 68 - II. 二叉树的最近公共祖先

    [LeetCode]剑指 Offer 68 - II. 二叉树的最近公共祖先 文章目录 [LeetCode]剑指 Offer 68 - II. 二叉树的最近公共祖先 一.DFS 一.DFS 祖先的定义 ...

  10. 【LeetCode】剑指 Offer 55 - I. 二叉树的深度

    [LeetCode]剑指 Offer 55 - I. 二叉树的深度 文章目录 [LeetCode]剑指 Offer 55 - I. 二叉树的深度 一.后序遍历(DFS) 二.层序遍历 一.后序遍历(D ...

最新文章

  1. android os被删除怎么办,手机系统应用误删了怎么办 如何修复手机异常【详细介绍】...
  2. Linux字体显示不同颜色
  3. 揭开雷达的面纱(科普)探测能力
  4. 【深入Java虚拟机JVM 05】HotSpot对象探秘
  5. 机械秒表的使用方法_瓦楞纸箱防水性能检测方法
  6. C# 网络编程之最简单浏览器实现
  7. Inno Setup入门(十八)——Inno Setup类参考(4)
  8. 三层交换(VLAN间互通+路由功能)+VTP+STP(PVST)综合实验(理论+实践=真实)
  9. vijos p1460——拉力赛
  10. 递归函数python有什么特点_Python中的递归
  11. Linux常用的命令及操作技巧
  12. oracle报03113,【案例】Oracle报错ORA-03113 ORA-15064产生原因和解决办法
  13. 第二个暴力猴脚本- 改写后用iframe抓取携程某个城市所有起飞、到达航班并保存
  14. vbm 分析_vbm分析 | Forum of resting-state fMRI
  15. 吉林省专升本历年真题高频词汇
  16. 考研高数 专题7:方程根的存在性及个数(零点定理-罗尔定理;单调性-罗尔定理推论)
  17. linux中,运行sh文件没权限错误:Permission denied,解决方法
  18. JS console.log()的理解
  19. MR混合现实头显来啦!宏碁微软产品率先上市
  20. SheetJS生成/解析Excel

热门文章

  1. android 安装第三方app,Android识别预装的第三方App方法实例
  2. Linux绘图函数与驱动,Linux中与驱动相关的ioctl函数
  3. sklearn的逻辑回归
  4. 【转】理解OAuth 2.0
  5. 高斯课堂数电讲义笔记_【法考经验贴】40岁三战主观题127分!他的笔记学习法助他逆袭!...
  6. Hbase2修复 - HBCK2
  7. druid加密mysql_Druid 数据库用户密码加密 代码实现
  8. 二进制枚举子集 CS Maxor 或运算,DP(SOS)
  9. 【POJ - 3616】Milking Time (贪心+dp)
  10. 【Gym - 101196F】Removal Game (环形区间dp,环状,细节优化)