剑指offer37.序列化二叉树

news2024/12/30 1:49:20

 先不讲题目,先讲讲序列化和反序列化。

一,序列化与反序列化

在Java中,序列化和反序列化是用于将对象转换为字节流和将字节流转换回对象的过程。序列化是将对象转换为字节流,以便可以在网络上传输或保存到文件中。而反序列化则是将字节流重新转换回对象。

Java提供了一个java.io.Serializable接口,通过实现该接口,可以使类变得可序列化。该接口是一个标记接口,不包含任何方法,仅用于标识类的实例可以进行序列化。当一个类实现了Serializable接口后,它的所有非瞬态(non-transient)的实例变量都可以被序列化。

下面是一个简单的示例,展示了如何在Java中进行序列化和反序列化:

import java.io.*;

public class SerializationDemo {
    public static void main(String[] args) {
        // 序列化对象
        try {
            // 创建对象
            MyClass obj = new MyClass("Hello, World!");

            // 创建文件输出流
            FileOutputStream fileOut = new FileOutputStream("object.ser");

            // 创建对象输出流
            ObjectOutputStream out = new ObjectOutputStream(fileOut);

            // 序列化对象
            out.writeObject(obj);

            // 关闭输出流
            out.close();

            // 关闭文件输出流
            fileOut.close();

            System.out.println("对象已序列化到 object.ser 文件");
        } catch (IOException e) {
            e.printStackTrace();
        }

        // 反序列化对象
        try {
            // 创建文件输入流
            FileInputStream fileIn = new FileInputStream("object.ser");

            // 创建对象输入流
            ObjectInputStream in = new ObjectInputStream(fileIn);

            // 反序列化对象
            MyClass obj = (MyClass) in.readObject();

            // 关闭输入流
            in.close();

            // 关闭文件输入流
            fileIn.close();

            System.out.println("从 object.ser 文件反序列化得到对象:");
            System.out.println(obj.getMessage());
        } catch (IOException | ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
}

class MyClass implements Serializable {
    private String message;

    public MyClass(String message) {
        this.message = message;
    }

    public String getMessage() {
        return message;
    }
}

在上面的示例中,我们创建了一个MyClass类,它实现了Serializable接口。然后,我们创建一个MyClass对象并将其序列化到文件object.ser中。接下来,我们从文件中反序列化对象,并打印出getMessage()方法返回的消息。

需要注意的是,如果一个类的某些字段不希望被序列化,可以将其标记为transient关键字。在上述示例中,如果message字段被声明为transient,那么它将不会被序列化。

另外,需要注意的是,序列化和反序列化的过程依赖于类的结构和版本。如果在序列化对象后,修改了类的结构或版本,那么在反序列化时可能会出现异常。为了避免这种情况,建议在类中声明一个名为serialVersionUID的静态常量,用于标识类的版本号。当类的结构或版本发生变化时,应更新serialVersionUID的值。这样可以确保反序列化时的兼容性。

这就是Java中序列化和反序列化的基本概念和用法。通过序列化和反序列化,可以方便地在Java应用程序之间或与外部系统之间传输对象数据。

---------------------------------------------------------------------------------------------------------------------------------

以上都是chatgpt生成的,总结一下就是,序列化把对象转换成字节流,为了方便在网络中传输和保存在硬盘,反序列化就反过来。通过实现ava.io.Serializable接口,可以使类变得可序列化。如果一个类的某些字段不希望被序列化,可以将其标记为transient关键字。

二,题解

public class Codec {

    // Encodes a tree to a single string.
    public String serialize(TreeNode root) {
        return rserialize(root, "");
    }

    // Decodes your encoded data to tree.
    public TreeNode deserialize(String data) {
        String[] dataArray = data.split(",");
        List<String> dataList = new LinkedList<String>(Arrays.asList(dataArray));
        return rdeseralize(dataList);
    }

    public String rserialize(TreeNode root, String str){
        if(root == null){
            str += "None,";
        }else{
            str += str.valueOf(root.val) + ",";
            str = rserialize(root.left, str);
            str = rserialize(root.right, str);
        }
        return str;
    }

    public TreeNode rdeseralize(List<String> dataList){
        if(dataList.get(0).equals("None")){
            dataList.remove(0);
            return null;
        }

        TreeNode root = new TreeNode(Integer.valueOf(dataList.get(0)));
        dataList.remove(0);
        root.left = rdeseralize(dataList);
        root.right = rdeseralize(dataList);

        return root;
    }
}

正真序列化与反序列化的方法是rserialize()和rdeserialize(),serialize()和deserialize()调用了这两个正真的序列化与反序列化方法。

rserialize()就是以根左右的方式遍历这个树,如果遍历到的节点是null,就在str后面加一个Node,否则就加”值,“,然后把它的左孩子加进去,然后把左孩子的左孩子加进去...然后加最小的右孩子...这样就完成了序列化,serialize()调用rserialize()就行。

deserialize()先用split方法把str以”,“分开,放入一个String数组里面,再通过Arrays.asList()方法转换成List,然后作为参数通过构造方法new一个LinkedList,然后调用rdeseralize()方法,这个方法传的参数就是一个包含每个节点值的list,这个值是Strign类型。

rdeseralize()是每次取出List的第一个元素,如果是”None“,就直接删掉返回一个null,否则就拿到这个元素通过Integer.valueOf()方法转换成Integer类型,创建一个新节点,节点的val就是这个值。然后删掉list的第一个元素,然后节点的左孩子调用这个方法,于是第二个元素就给了节点的左孩子,这样就实现了与序列化相反的反序列化。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/757365.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

jb2文件在web端展示之easyJBIG2show

easyJBIG2show an easy JBIG2 file web show github地址 一、背景 最近无意中接触到了一个二维码图片&#xff0c;该图片格式是jb2格式。翻阅资料发现JBIG标准最初在1993年发布&#xff0c;在当时被广泛应用于传真机和文档扫描仪等设备中。JBIG采用了一种自适应二进制编码算…

7.14~7.15学习总结

Java的前置知识学习时间截至了&#xff0c;慌的一批~~。 看看自己学的&#xff0c;再看看要求学的&#xff0c;简直&#xff1a; 现在继续&#xff1a;IO流里面的Commons_IO的用法&#xff1a; public class Main {public static void main(String[]args) throws IOException…

初识Linux——“Linux”

各位CSDN的uu们你们好呀&#xff0c;今天&#xff0c;小雅兰开了一个全新的专栏啦&#xff0c;这就是Linux&#xff0c;下面&#xff0c;让我们一起进入Linux的世界吧&#xff01;&#xff01;&#xff01; Linux 背景介绍 搭建 Linux 环境 使用 XShell 远程登陆到 Linux Lin…

图片速览 DCN K-means-friendly Spaces: Simultaneous Deep Learning and Clustering

本文使用了一种交替更新网络参数和聚类中心的方法。在网络更新完成之后&#xff0c;对于固定的网络参数和 M&#xff0c;再更新当前样本的分配向量。然后根据新的分配结果如式子3.8更新聚类中心&#xff1a; 注&#xff1a;文中还有问题是否能进行凸优化的部分 CG https…

35 用户虚拟地址空间的 堆栈区间初始化

前言 对于用户程序来说, 堆栈区间 是一个很重要的组成部分, 这部分核心用于支持 函数调用, 参数暂存, 局部变量的存储 等等 我们这里 就来看一下 这块空间 的初始化的相关情况 这里会结合 内核进行调试, 以及 内存中的数据进行分析 堆栈空间的初始化 stack_base, stack_…

【Megatron-DeepSpeed】张量并行工具代码mpu详解(二):Collective通信操作的封装mappings

相关博客 【Megatron-DeepSpeed】张量并行工具代码mpu详解(一)&#xff1a;并行环境初始化 【Megatron-DeepSpeed】张量并行工具代码mpu详解(二)&#xff1a;Collective通信操作的封装mappings 【深度学习】【分布式训练】DeepSpeed&#xff1a;AllReduce与ZeRO-DP 【深度学习】…

day27 贪心算法

1.什么是贪心&#xff1f; 比如10张钞票&#xff0c;有1&#xff0c;5&#xff0c;20&#xff0c;100等面额&#xff0c;取五张&#xff0c;如何取得到数额最多的钱&#xff1f;每次取面额最大的那张钞票&#xff1b;就是每个阶段的局部最优&#xff1b;全局最优就是最后拿到的…

扫雷游戏制作

扫雷 0 目录 前言 游戏三部曲 游戏设计 函数说明 程序打包 1 前言 终极目标&#xff1a;打造多关卡扫雷游戏 制作环境: VS2015 支持:VC2010 VS各个版本 easyx图形库(点我) 一直想发表扫雷这种锻炼思维的游戏&#xff0c;其实扫雷弄个标题栏可以随意选择挑战…

从小白到大神之路之学习运维第60天--------Ansible自动化运维工具(安装、操作、简单使用,模块的作用)

第三阶段基础 时 间&#xff1a;2023年7月13日 参加人&#xff1a;全班人员 内 容&#xff1a; Ansible自动化运维工具 目录 一、Ansible概述 二、Ansible特点 三、Ansible应用 &#xff08;一&#xff09;使用者 &#xff08;二&#xff09;Ansible工具集合 &…

Spring Cloud Alibaba 整合 Nacos 实战

Spring Cloud Alibaba 整合 Nacos 实战 一、Nacos的服务注册和发现机制1. Nacos 的服务注册和发现机制可以分为以下几个步骤&#xff1a;1.1. 服务注册&#xff1a;1.2. 服务发现&#xff1a;1.3. 心跳机制&#xff1a;1.4. 服务下线&#xff1a; 2. Nacos 的服务注册和发现机制…

【burpsuite安全练兵场-客户端15】基于DOM的漏洞-7个实验(全)

前言&#xff1a; 介绍&#xff1a; 博主&#xff1a;网络安全领域狂热爱好者&#xff08;承诺在CSDN永久无偿分享文章&#xff09;。 殊荣&#xff1a;CSDN网络安全领域优质创作者&#xff0c;2022年双十一业务安全保卫战-某厂第一名&#xff0c;某厂特邀数字业务安全研究员&…

python接口自动化(三十八)-python操作mysql数据库(详解)

简介 现在的招聘要求对QA人员的要求越来越高&#xff0c;测试的一些基础知识就不必说了&#xff0c;来说测试知识以外的&#xff0c;会不会一门或者多门开发与语言&#xff0c;能不能读懂代码&#xff0c;会不会Linux&#xff0c;会不会搭建测试系统&#xff0c;会不会常用的数…

STL容器 -- vector的模拟实现(配详细注释)

目录 一、vector容器是什么&#xff1f;二、vector的模拟实现2.1 vector的成员变量2.2 构造函数2.2.1 无参构造函数2.2.2 有参构造函数 2.3 拷贝构造函数2.4 赋值重载函数2.5 析构函数2.6 reserve函数2.7 resize函数2.8 insert函数2.9 erase函数2.10 push_back和pop_back函数2.…

数据结构05:树与二叉树[C++][线索二叉树:先序、后序]

图源&#xff1a;文心一言 本篇博文含{先序线索化的代码与后序线索化的代码}&#xff0c;由于模板字数限制&#xff0c;中序线索化的代码及线索化的原理简介在上一篇博文~&#x1f95d;&#x1f95d; 数据结构05&#xff1a;树与二叉树[C][线索二叉树&#xff1a;中序]_梅头脑…

Linux 系统编程-开发环境(一)

目录 1 shell 1.1 shell 家族 1.2 bash 1.3 命令和路径补齐 1.4 历史记录 1.5 主键盘快捷键 1.6 演示 2 目录和文件 2.1 类Unix系统目录结构 2.2 用户目录 2.2.1 相对路径和绝对路径 2.3 ls 2.4 cd 2.5 which 2.6 pwd 2.7 mkdir 2.8 rmdir 2.9 touch 2.10…

在AndroidStudio中开发系统APP

1.AndroidStudio项目中调用系统API AndroidStudio项目中调用系统API&#xff08;比如调用 UnsupportedAppUsage 的方法&#xff09;&#xff0c;需要引入系统framework.jar包。 第一步如下图&#xff0c;fremework.jar 放在app/systemjar/目录下 第二步&#xff0c;在app下的…

Win10点击任务栏搜索、日历无响应

现象描述 点击Win10任务搜索栏和日历均无响应 解决方法 1、无响应应该是程序发生了异常&#xff0c;通过Windows日志产看器发现是KERNELBASE.dll模块发生了0x88985004异常。 2&#xff0c;查看错误代码含义 3&#xff0c;在微软社区查看此类问题&#xff0c;重点关注与字…

RocketMQ快速使用基础

1. RocketMQ 介绍 RocketMQ作为一款纯java、分布式、队列模型的开源消息中间件&#xff0c;支持事务消息、顺序消息、批量消息、定时消息、消息回溯等 前身是MetaQ&#xff0c;是阿里研发的一个队列模型的消息中间件&#xff0c;后开源给apache基金会成为了apache的顶级开源项目…

基于SaaS模式的Java基层卫生健康云HIS系统源码【运维管理+运营管理+综合监管】

云HIS综合管理平台 一、模板管理 模板分为两种&#xff1a;病历模板和报表模板。模板管理是运营管理的核心组成部分&#xff0c;是基层卫生健康云中各医疗机构定制电子病历和报表的地方&#xff0c;各医疗机构可根据自身特点特色定制电子病历和报表&#xff0c;制作的电子病历…

【Kubernetes运维篇】RBAC之创建集群用户管理K8S

文章目录 一、创建zhangsan集群用户赋予uat名称空间管理员权限二、创建lisi集群用户赋予查看所有名称Pod权限 需求&#xff1a;公司新入职两位运维同事&#xff0c;分别是zhangsan、lisi&#xff0c;刚入职肯定不能给K8S管理员权限&#xff0c;所以需要创建两个系统账号&#x…