【剑指Offer学习】【面试题62:序列化二叉树】
题目:请实现两个函数,分别用来序列化和反序列化二叉树。
解题思路
通过分析解决前面的面试题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:序列化二叉树】的更多相关文章
- 《剑指offer》面试题37. 序列化二叉树
问题描述 请实现两个函数,分别用来序列化和反序列化二叉树. 示例: 你可以将以下二叉树: 1 / \ 2 3 / \ 4 5 序列化为 "[1,2,3,null,null,4,5]&quo ...
- 《剑指offer》面试题62. 圆圈中最后剩下的数字
问题描述 0,1,n-1这n个数字排成一个圆圈,从数字0开始,每次从这个圆圈里删除第m个数字.求出这个圆圈里剩下的最后一个数字. 例如,0.1.2.3.4这5个数字组成一个圆圈,从数字0开始每次删除第 ...
- (剑指Offer)面试题25:二叉树中和为某一值的路径
题目: 输入一颗二叉树和一个整数,打印出二叉树中结点值的和为输入整数的所有路径.路径定义为从树的根结点开始往下一直到叶结点所经过的结点形成一条路径. 二叉树结点的定义: struct TreeNode ...
- (剑指Offer)面试题19:二叉树的镜像
题目: 操作给定的二叉树,将其变换为源二叉树的镜像. 二叉树的定义如下: struct TreeNode{ int val; TreeNode* left; TreeNode* right; }; 输 ...
- 【剑指offer】面试题39:二叉树的深度
题目: 输入一棵二叉树,求该树的深度.从根结点到叶结点依次经过的结点(含根.叶结点)形成树的一条路径,最长路径的长度为树的深度. 思路: 根的深度=MAX(左子树深度,右子树深度)+1; Code: ...
- 【剑指offer】面试题25:二叉树中和为某一值的路径
题目: 输入一颗二叉树和一个整数,打印出二叉树中结点值的和为输入整数的所有路径.路径定义为从树的根结点开始往下一直到叶结点所经过的结点形成一条路径. 思路: dfs一下就可以了.一般dfs肯定递归写比 ...
- (剑指Offer)面试题58:二叉树的下一个结点
题目: 给定一个二叉树和其中的一个结点,请找出中序遍历顺序的下一个结点并且返回.注意,树中的结点不仅包含左右子结点,同时包含指向父结点的指针. 思路: 考虑中序遍历的过程, 如果当前结点存在右子节点, ...
- (剑指Offer)面试题39:二叉树的深度
题目: 输入一棵二叉树,求该树的深度.从根结点到叶结点依次经过的结点(含根.叶结点)形成树的一条路径,最长路径的长度为树的深度. 结点的定义如下: struct TreeNode{ int val; ...
- 剑指offer笔记面试题7----重建二叉树
题目:输入某二叉树的前序遍历和中序遍历的结果,请重建该二叉树.假设输入的前序遍历和中序遍历的结果中都不含重复的数字.例如,输入前序遍历序列{1, 2, 4, 7, 3, 5, 6, 8}和中序遍历序列 ...
- 《剑指offer》面试题6 重建二叉树 Java版
(由一个二叉树的前序和中序序列重建一颗二叉树) 书中方法:我们要重建一棵二叉树,就要不断地找到根节点和根节点的左子结点和右子节点.注意前序序列, 它的第一个元素就是二叉树的根节点,后面的元素分为它的左 ...
随机推荐
- poj 1418 Viva Confetti
Viva Confetti Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 1025 Accepted: 422 Desc ...
- SqlLite 安装与使用
一.安装文件 官方下载地址: http://system.data.sqlite.org/index.html/doc/trunk/www/downloads.wiki 选择要下载的类库文件:sqli ...
- 转 Python爬虫入门三之Urllib库的基本使用
静觅 » Python爬虫入门三之Urllib库的基本使用 1.分分钟扒一个网页下来 怎样扒网页呢?其实就是根据URL来获取它的网页信息,虽然我们在浏览器中看到的是一幅幅优美的画面,但是其实是由浏览器 ...
- VUE之Router命令行警告:Named Route 'Home' has a default child route. 解决办法
Named Route 'Home' has a default child route. When navigating to this named route (:to="{name: ...
- HAXM 6.0.5显示不兼容Windows
HAXM 6.0.5显示不兼容Windows 最近更新Android后,用户会在Android Manager中发现,以前可以安装Intel x86模拟器现在不能安装了.提示错误信息如下:intel ...
- HTML5 一些有用的 APIs
Animation Timing Window.requestAnimationFrame(callback): 告诉浏览器希望执行一个动画,让浏览器在下一个动画帧安排一次网页重绘(类似于 setTi ...
- Hibernate中的对象状态,及自动更新原因,Hibernate set对象后不调用update却自动更新
原文:http://www.cnblogs.com/xiaoda/p/3225617.html Hibernate的对象有三种状态,分别为:瞬时状态 (Transient). 持久化状态(Persis ...
- 给button添加长按手势并侦测到此button
1, 添加手势 self.longPressRecognizer = [[UILongPressGestureRecognizer alloc]initWithTarget:self action:@ ...
- Android常见的三种内部类
在java里类中再定义类,这种在其他类内部类叫做内部类,在Android开发里最常见有三种内部类分别是(成员内部类.方法内部类.匿名内部类) 一.成员内部类 1 public class Test { ...
- Android学习笔记(35):Android活动条
在Android3.0之后,Google对UI导航设计上进行了一系列的改革,当中有一个很好用的新功能就是引入的ActionBar,用于代替3.0之前的标题栏,并提供更为丰富的导航效果. ActionB ...