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


解题思路

  通过分析解决前面的面试题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. java maven项目testng执行时使用的是test-classes下的文件,共享main下方resource的配置

    在pom.xml中配置 <build> <testResources> <testResource> <directory>${project.base ...

  2. ELK安装文档

    ELK安装文档: http://cuidehua.blog.51cto.com/5449828/1769525 如何将客户端日志通过ogstash-forwarder发送给服务端的logstash h ...

  3. fzu 1753 质因数的应用

    Another Easy Problem Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64 ...

  4. 【CF666B】World Tour(贪心,最短路)

    题意:给你一张有向图,叫你给出四个点的序列a,b,c,d,使得这四个点依次间的最短路之和最大.(4 ≤ n ≤ 3000, 3 ≤ m ≤ 5000) 思路:O(n4)可用来对拍 我们需要O(n2)级 ...

  5. POJ 3107 Godfather (树重心)

    题目链接:http://poj.org/problem?id=3107 题意: 数重心,并按从小到大输出. 思路: dfs #include <iostream> #include < ...

  6. Uoj #350. 新年的XOR

    前缀异或和是可以讨论的,非常naive,然后这就是个水题了23333 #include<bits/stdc++.h> #define ll long long using namespac ...

  7. JD路径配置及myeclipse主题和提示设置

    1. JDKAN安装及环境变量配置 安装jdk,注意记住安装路径(F:\Java\jdk1.8.0_121 )(个人爱好) 系统变量→新建 JAVA_HOME 变量 . 变量值填写jdk的安装目录(F ...

  8. openssl转换各种证书的语法收集

    参考网址:https://www.sslshopper.com/ssl-converter.html 个人总结:先找准要生成什么证书先,尤其是正规购买的流程与openssl生成的不一样,所以先确定是什 ...

  9. GLSL预定义变量

    GLSL为不同的渲染阶段定义了一些特定的变量.这些预定义(也叫做内置变量)有特定的属性.所有的预定义变量都以gl_开头.用户定义的变量不能以此开头. 下面分类进行介绍. (1)顶点着色器输入 in i ...

  10. 好用的Python IDLE Sublime Text 3推荐

    Sublime Text 3 下载地址为 LINK, Sublime Text 3 is currently in beta. The latest build is 3114. 参考的激活方式为输入 ...