面试算法48:序列化和反序列化二叉树

题目

请设计一个算法将二叉树序列化成一个字符串,并能将该字符串反序列化出原来二叉树的算法。

分析

先考虑如何将二叉树序列化为一个字符串。需要逐个遍历二叉树的每个节点,每遍历到一个节点就将节点的值序列化到字符串中。以前序遍历的顺序遍历二叉树最适合序列化。如果采用前序遍历的顺序,那么二叉树的根节点最先序列化到字符串中,然后是左子树,最后是右子树。这样做的好处是在反序列化时最方便,从字符串中读出的第1个数值一定是根节点的值。

实际上,只把节点的值序列化到字符串中是不够的。首先,要用一个分隔符(如逗号)把不同的节点分隔开。其次,还要考虑如何才能在反序列化的时候构建不同结构的二叉树。

尽管null节点通常没有在图上画出来,但它们对树的结构是至关重要的。因此,应该把null节点序列化成一个特殊的字符串。如果把null节点序列化成"#",那么图8.3(a)中的二叉树用前序遍历将被序列化成字符串"6,6,6,#,#,6,#,#,6,#,#",而图8.3(b)中的二叉树将被序列化成字符串"6,6,#,#,6,6,#,#,6,#,#"。

java 复制代码
public class Test {
    public static void main(String[] args) {
        TreeNode node6 = new TreeNode(6);
        TreeNode node66 = new TreeNode(6);
        TreeNode node666 = new TreeNode(6);
        TreeNode node6666 = new TreeNode(6);
        TreeNode node66666 = new TreeNode(6);

        node6.left = node66;
        node6.right = node666;
        node66.left = node6666;
        node66.right = node66666;

        String result = serialize(node6);
        System.out.println(result);
        TreeNode deserialize = deserialize(result);
        System.out.println(deserialize);
    }

    public static String serialize(TreeNode root) {
        if (root == null) {
            return "#";
        }

        String leftStr = serialize(root.left);
        String rightStr = serialize(root.right);
        return root.val + "," + leftStr + "," + rightStr;
    }

    public static TreeNode deserialize(String data) {
        String[] nodeStrs = data.split(",");
        int[] array = {0};
        return dfs(nodeStrs, array);
    }

    private static TreeNode dfs(String[] strs, int[] array) {
        String str = strs[array[0]];
        array[0]++;

        if (str.equals("#")) {
            return null;
        }

        TreeNode node = new TreeNode(Integer.valueOf(str));
        node.left = dfs(strs, array);
        node.right = dfs(strs, array);
        return node;
    }
}
相关推荐
我叫黑大帅7 分钟前
其实跨域问题是后端来解决的? CORS
后端·面试·go
掘金安东尼1 小时前
OpenMUSE 全面详解:非扩散Transformer文生图开源基座(对标GPT Image 2)
前端·javascript·面试
下次再写1 小时前
Java互联网大厂面试技术问答实战:涵盖Java SE、Spring Boot、微服务及多场景应用
java·数据库·缓存·面试·springboot·microservices·技术问答
memcpy01 小时前
LeetCode 2452. 距离字典两次编辑以内的单词【暴力;字典树】中等
算法·leetcode·职场和发展
千寻girling1 小时前
RabbitMQ 详细教程(38K字数)
java·后端·面试
山栀shanzhi1 小时前
在做直播时,I帧的间隔(GOP)一般是多少?
网络·c++·面试·ffmpeg
卷毛的技术笔记1 小时前
从“拆东墙补西墙”到“最终一致”:分布式事务在Spring Boot/Cloud中的破局之道
java·spring boot·分布式·后端·spring cloud·面试·rocketmq
王老师青少年编程1 小时前
csp信奥赛C++高频考点专项训练之贪心算法 --【排序贪心】:魔法
c++·算法·贪心·csp·信奥赛·排序贪心·魔法
wearegogog1231 小时前
基于和差波束法的单脉冲测角MATLAB实现
人工智能·算法·matlab
AI科技星2 小时前
灵魂商数(SQ) · 全域数学统一定义【乖乖数学】
算法·机器学习·数学建模·数据挖掘·量子计算