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


解题思路

  通过分析解决前面的面试题6.我们知道能够从前序遍历和中序遍历构造出一棵二叉树。受此启示。我们能够先把一棵二叉树序列化成一个前序遍历序列和一个中序序列。然后再反序列化时通过这两个序列重构出原二叉树。

  这个思路有两个缺点。一个缺点是该方法要求二叉树中不能用有数值反复的结点。

另外仅仅有当两个序列中全部数据都读出后才干開始反序列化。

假设两个遍历序列的数据是从一个流里读出来的,那就可能须要等较长的时间。

  实际上假设二叉树的序列化是从根结点開始的话,那么对应的反序列化在根结点的数值读出来的时候就能够開始了。因此我们能够依据前序遍历的顺序来序列化二叉树。由于前序遍历是从根结点開始的。

当在遍历二叉树碰到NULL指针时,这些NULL指针序列化成一个特殊的字符(比方‘$’)。

另外,结点的数值之间要用一个特殊字符(比方’,’)隔开。

结点定义

private static class BinaryTreeNode {
private int val;
private BinaryTreeNode left;
private BinaryTreeNode right; public BinaryTreeNode() {
} public BinaryTreeNode(int val) {
this.val = val;
} @Override
public String toString() {
return val + "";
}
}

代码实现

import java.util.LinkedList;
import java.util.List; public class Test62 {
private static class BinaryTreeNode {
private int val;
private BinaryTreeNode left;
private BinaryTreeNode right; public BinaryTreeNode() {
} public BinaryTreeNode(int val) {
this.val = val;
} @Override
public String toString() {
return val + "";
}
} public static void serialize(BinaryTreeNode root, List<Integer> result) { List<BinaryTreeNode> list = new LinkedList<>();
list.add(root);
BinaryTreeNode node;
while (list.size() > 0) {
node = list.remove(0);
if (node == null) {
result.add(null);
}else {
result.add(node.val);
list.add(node.left);
list.add(node.right);
}
}
} public static BinaryTreeNode deserialize(List<Integer> result, int idx) { if (result.size() < 1 || idx < 0 || result.size() <= idx || result.get(idx) == null) {
return null;
} BinaryTreeNode root = new BinaryTreeNode(result.get(idx));
root.left = deserialize(result, idx * 2 + 1);
root.right = deserialize(result, idx * 2 + 2);
return root; } public static void main(String[] args) {
test01();
} private static void test01() {
BinaryTreeNode n1 = new BinaryTreeNode(1);
BinaryTreeNode n2 = new BinaryTreeNode(2);
BinaryTreeNode n3 = new BinaryTreeNode(3);
BinaryTreeNode n4 = new BinaryTreeNode(4);
BinaryTreeNode n5 = new BinaryTreeNode(5);
BinaryTreeNode n6 = new BinaryTreeNode(6);
BinaryTreeNode n7 = new BinaryTreeNode(7);
BinaryTreeNode n8 = new BinaryTreeNode(8);
BinaryTreeNode n9 = new BinaryTreeNode(9); n1.left = n2;
n1.right = n3;
n2.left = n4;
n2.right = n5;
n3.left = n6;
n3.right = n7;
n4.left = n8;
n4.right = n9; List<Integer> result = new LinkedList<>();
serialize(n1, result);
System.out.println(result);
System.out.println(); BinaryTreeNode root = deserialize(result, 0) ;
print(root); } private static void print(BinaryTreeNode root) {
if (root != null) {
print(root.left);
System.out.printf("%-3d", root.val);
print(root.right);
}
}
}

执行结果

特别说明

欢迎转载。转载请注明出处【http://blog.csdn.net/DERRANTCM/article/details/46857985

【剑指Offer学习】【面试题62:序列化二叉树】的更多相关文章

  1. 《剑指offer》面试题37. 序列化二叉树

    问题描述 请实现两个函数,分别用来序列化和反序列化二叉树. 示例:  你可以将以下二叉树: 1 / \ 2 3 / \ 4 5 序列化为 "[1,2,3,null,null,4,5]&quo ...

  2. 《剑指offer》面试题62. 圆圈中最后剩下的数字

    问题描述 0,1,n-1这n个数字排成一个圆圈,从数字0开始,每次从这个圆圈里删除第m个数字.求出这个圆圈里剩下的最后一个数字. 例如,0.1.2.3.4这5个数字组成一个圆圈,从数字0开始每次删除第 ...

  3. (剑指Offer)面试题25:二叉树中和为某一值的路径

    题目: 输入一颗二叉树和一个整数,打印出二叉树中结点值的和为输入整数的所有路径.路径定义为从树的根结点开始往下一直到叶结点所经过的结点形成一条路径. 二叉树结点的定义: struct TreeNode ...

  4. (剑指Offer)面试题19:二叉树的镜像

    题目: 操作给定的二叉树,将其变换为源二叉树的镜像. 二叉树的定义如下: struct TreeNode{ int val; TreeNode* left; TreeNode* right; }; 输 ...

  5. 【剑指offer】面试题39:二叉树的深度

    题目: 输入一棵二叉树,求该树的深度.从根结点到叶结点依次经过的结点(含根.叶结点)形成树的一条路径,最长路径的长度为树的深度. 思路: 根的深度=MAX(左子树深度,右子树深度)+1; Code: ...

  6. 【剑指offer】面试题25:二叉树中和为某一值的路径

    题目: 输入一颗二叉树和一个整数,打印出二叉树中结点值的和为输入整数的所有路径.路径定义为从树的根结点开始往下一直到叶结点所经过的结点形成一条路径. 思路: dfs一下就可以了.一般dfs肯定递归写比 ...

  7. (剑指Offer)面试题58:二叉树的下一个结点

    题目: 给定一个二叉树和其中的一个结点,请找出中序遍历顺序的下一个结点并且返回.注意,树中的结点不仅包含左右子结点,同时包含指向父结点的指针. 思路: 考虑中序遍历的过程, 如果当前结点存在右子节点, ...

  8. (剑指Offer)面试题39:二叉树的深度

    题目: 输入一棵二叉树,求该树的深度.从根结点到叶结点依次经过的结点(含根.叶结点)形成树的一条路径,最长路径的长度为树的深度. 结点的定义如下: struct TreeNode{ int val; ...

  9. 剑指offer笔记面试题7----重建二叉树

    题目:输入某二叉树的前序遍历和中序遍历的结果,请重建该二叉树.假设输入的前序遍历和中序遍历的结果中都不含重复的数字.例如,输入前序遍历序列{1, 2, 4, 7, 3, 5, 6, 8}和中序遍历序列 ...

  10. 《剑指offer》面试题6 重建二叉树 Java版

    (由一个二叉树的前序和中序序列重建一颗二叉树) 书中方法:我们要重建一棵二叉树,就要不断地找到根节点和根节点的左子结点和右子节点.注意前序序列, 它的第一个元素就是二叉树的根节点,后面的元素分为它的左 ...

随机推荐

  1. ACE的饼图显示保留两位小数

    修改源js文件:jquery.flot.pie.min.js <script src="/static/assets/js/jquery.flot.pie.min.js"&g ...

  2. 微信小程序中 input组件影响页面样式的问题

    input组件有个默认的宽高,好像是不能清除的,在使用flex布局的时候,发现会影响到页面的布局,以为是flex布局的问题,改为float布局试了下也是同样的问题,试着把input标签换成别的标签,问 ...

  3. (超详细)使用git命令行将本地仓库代码上传到github或gitlab远程仓库

    (超详细)使用git命令行将本地仓库代码上传到github或gitlab远程仓库 本地创建了一个 xcode 工程项目,现通过 命令行 将该项目上传到 github 或者 gitlab 远程仓库,具体 ...

  4. php--strlen()与mb_strlen的作用与区别

    在PHP中,strlen与mb_strlen是求字符串长度的函数PHP内置的字符串长度函数strlen无法正确处理中文字符串,它得到的只是字符串所占的字节数.对于GB2312的中文编码,strlen得 ...

  5. poj 2112(二分+网络流)

    Optimal Milking Time Limit: 2000MS   Memory Limit: 30000K Total Submissions: 15749   Accepted: 5617 ...

  6. 通过jQuery Ajax提交表单数据时同时上传附件

    1.使用场景:需要使用ajax提交表单,但是提交的表单里含有附件上传 2.代码实现方式: <!-- HTML代码 --> <form method="post" ...

  7. Codeforces 946 A.Partition

    随便写写,然后写D的题解. A. Partition   time limit per test 1 second memory limit per test 256 megabytes input ...

  8. NYOJ90 整数划分(经典递归和dp)

    整数划分 时间限制:3000 ms  |  内存限制:65535 KB 难度:3   描述 将正整数n表示成一系列正整数之和:n=n1+n2+…+nk,  其中n1≥n2≥…≥nk≥1,k≥1.  正 ...

  9. 可能是全网最详细的express--middleware

    写在前面 hello,小伙伴们,我是你们的pubdreamcc,本篇博文出至于我的GitHub仓库node学习教程资料,欢迎小伙伴们点赞和star,你们的点赞是我持续更新的动力. GitHub仓库地址 ...

  10. Light oj 1134 - Be Efficient (前缀和)

    题目链接:http://www.lightoj.com/volume_showproblem.php?problem=1134 题意: 给你n个数,问你多少个连续的数的和是m的倍数. 思路: 前缀和取 ...