剑指offer第二版-37.序列化二叉树

本系列导航:剑指offer(第二版)java实现导航帖

面试题37:序列化二叉树

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

解题思路:
此题能让人想到重建二叉树。但二叉树序列化为前序遍历序列和中序遍历序列,然后反序列化为二叉树的思路在本题有两个关键缺点:1.全部数据都读取完才能进行反序列化。2.该方法需要保证树中节点的值各不相同(本题无法保证)。
其实,在遍历结果中,记录null指针后(比如用一个特殊字符$),那么任何一种遍历方式都能回推出原二叉树。但是如果期望边读取序列化数据,边反序列化二叉树,那么仅可以使用前序或层序遍历。但层序记录的null个数要远多于前序,因此选择使用记录null指针的前序遍历进行序列化。

package chapter4;
import structure.TreeNode;

/**
 * Created by ryder on 2017/7/19.
 * 序列化二叉树
 */
public class P194_SerializeBinaryTrees {
    public static String serialize(TreeNode<Integer> root){
        if(root==null)
            return "$,";
        StringBuilder result = new StringBuilder();
        result.append(root.val);
        result.append(",");
        result.append(serialize(root.left));
        result.append(serialize(root.right));
        return result.toString();
    }
    public static TreeNode<Integer> deserialize(String str){
        StringBuilder stringBuilder = new StringBuilder(str);
        return deserializeCore(stringBuilder);
    }
    public static TreeNode<Integer> deserializeCore(StringBuilder stringBuilder){
        if(stringBuilder.length()==0)
            return null;
        String num = stringBuilder.substring(0,stringBuilder.indexOf(","));
        stringBuilder.delete(0,stringBuilder.indexOf(","));
        stringBuilder.deleteCharAt(0);
        if(num.equals("$"))
            return null;
        TreeNode<Integer> node = new TreeNode<>(Integer.parseInt(num));
        node.left = deserializeCore(stringBuilder);
        node.right = deserializeCore(stringBuilder);
        return node;
    }
    public static void main(String[] args){
        //            1
        //          /   \
        //         2     3
        //       /      / \
        //      4      5   6
        //    1,2,4,$,$,$,3,5,$,$,6,$,$
        TreeNode<Integer> root = new TreeNode<Integer>(1);
        root.left = new TreeNode<Integer>(2);
        root.right = new TreeNode<Integer>(3);
        root.left.left = new TreeNode<Integer>(4);
        root.right.left = new TreeNode<Integer>(5);
        root.right.right = new TreeNode<Integer>(6);
        System.out.println("原始树:"+root);
        String result = serialize(root);
        System.out.println("序列化结果:"+result);
        TreeNode<Integer> deserializeRoot = deserialize(result);
        System.out.println("反序列后的树:"+deserializeRoot);
    }
}

运行结果

原始树:[1,2,3,4,5,6]
序列化结果:1,2,4,$,$,$,3,5,$,$,6,$,$,
反序列后的树:[1,2,3,4,5,6]

推荐阅读更多精彩内容

  • 树的概述 树是一种非常常用的数据结构,树与前面介绍的线性表,栈,队列等线性结构不同,树是一种非线性结构 1.树的定...
    Jack921阅读 3,251评论 1 30
  • 面试题7:重建二叉树 题目: 输入某二叉树的前序遍历和中序遍历的结果。请重建该二叉树。假设输入的前序遍历和中序遍历...
    lyoungzzz阅读 172评论 0 0
  • 数据结构和算法--二叉树的实现 几种二叉树 1、二叉树 和普通的树相比,二叉树有如下特点: 每个结点最多只有两棵子...
    sunhaiyu阅读 3,595评论 0 14
  • 四、树与二叉树 1. 二叉树的顺序存储结构 二叉树的顺序存储就是用数组存储二叉树。二叉树的每个结点在顺序存储中都有...
    MinoyJet阅读 777评论 0 7
  • 总结 想清楚再编码 分析方法:举例子、画图 第1节:画图分析方法 对于二叉树、二维数组、链表等问题,都可以采用画图...
    M_巴拉巴拉阅读 914评论 0 7