二叉树的序列化与反序列化

news2024/11/18 14:01:50

二叉树的序列化与反序列化

  通俗的说就是给定一个二叉树的根节点,用某种方法将树结构的信息存到一个字符串中,并且还可以用这一个字符串还原这棵树。

  本文介绍两种方法,分别为递归法和迭代法。

剑指 Offer 37. 序列化二叉树

  

  

递归法

  • 序列化:将树信息存到一个字符串中

  将树的先序遍历结果存到字符串中,并将nullptr 用特殊符号#来表示。注意节点的值要从整型变为字符串。

在这里插入图片描述

  则存储的字符串信息为:msg = "1,2,#,#,3,4,#,#,5,#,#"

  逗号的意义时,还原串信息时作为两个节点信息的分隔符

  

  • 反序列化:通过之前存放树信息的那个字符串将树还原
细节处理,可以先把msg尾部添加一个 ',' 便于统一处理

msg中1,2,3,4都是字符,如果两位数,三位数,就是字符串。
需要先把他们翻译回整形,这样递归建树时便于处理。同时去除逗号这个对还原树操作无用信息。

特殊字符#,可以翻译成数据范围外的整型值

可以用整形数组存放处理之后的信息

则原 msg = "1,2,#,#,3,4,#,#,5,#,#," (第一步在最后加个逗号)
变为 (字符'#' 用32位极小值表示)
vector<int> msg = [1 2 -2147483648 -2147483648 3 4 -2147483648 -2147483648 5 -2147483648 -2147483648]

最后用这个msg信息开始建树即可
  • 代码
/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Codec {
public:

    // Encodes a tree to a single string.
    string serialize(TreeNode* root) {
        if (root == nullptr)  return "#";
        return to_string(root->val) + ',' + serialize(root->left) + ',' + serialize(root->right); 
    }


    TreeNode* __deserialize(vector<int> &msg, int &ind) {
        if (msg[ind] == INT32_MIN) {
            ++ind;
            return nullptr;
        }
        TreeNode *s = new TreeNode(msg[ind++]);
        s->left = __deserialize(msg, ind);
        s->right = __deserialize(msg, ind);
        return s;
    }

    // Decodes your encoded data to tree.
    TreeNode* deserialize(string data) {
        string t;
        data += ',';
        vector<int> msg;
        for (int i = 0; data[i]; ++i) {
            if (data[i] == ',') {
                if (t == "#")  msg.push_back(INT32_MIN);
                else  msg.push_back(stoi(t));
                t = "";
                continue;
            }
            t += data[i];
        }
        int ind = 0;
        return __deserialize(msg, ind);
    }
};

// Your Codec object will be instantiated and called as such:
// Codec codec;
// codec.deserialize(codec.serialize(root));

  

  

迭代法

  • 序列化:将树信息存到一个字符串中

  用广义表的形式存放树的信息

注意:

  • 生成广义表用递归法,通过广义表还原树用迭代法

  • 广义表还原树时,不用递归(系统栈),但要手动开辟栈结构辅助

  • 相比递归法字符串的长度,广义表的长度更长。因为迭代需要存储树的回溯信息。

  • 其实空间换时间——广义表相对长一点信息(空间),递归函数调用的开销(时间)

在这里插入图片描述

  则存储的字符串信息为:msg = "1(2(,),3(4(,),5(,)))"

  

  • 反序列化:通过之前存放树信息的那个字符串将树还原
手动开辟一个栈,存放节点指针,模拟系统栈
用一个变量flag_r表示当前节点是栈顶指针(父节点)的左子树还是右子树
用一个临时字符串str存单个节点信息

'(' : 
	Ⅰ.遇到这个字符则证明要处理当前节点的子节点了,所以当前节点信息已经通过str保存完整了。
	Ⅱ.既然完整就用str这份信息新建一个树节点(转换为整型)。同时清空str
	Ⅲ.看当前新节点是哪个节点的左子树还是右子树(栈顶元素指向当前点的父节点)
	Ⅳ.将新节点压入栈中,表示要处理它的子节点了。同时flag_r = false,下一步处理左子树
	
')' : 已经处理完了当前父节点的两个孩子,栈顶元素弹出

',' : 表示要处理右孩子了,flag_r = true,并且str清空

其它:节点值的信息用str连接存下来
  • 代码
/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Codec {
public:

    // Encodes a tree to a single string.
    string serialize(TreeNode* root) {
        if (root == nullptr)  return "";
        return to_string(root->val) + "(" + serialize(root->left) + "," + serialize(root->right) + ")";  
    }

    // Decodes your encoded data to tree.
    TreeNode* deserialize(string data) {
        stack<TreeNode *> s;
        TreeNode *ans = nullptr;
        bool flag_r = false;
        string str;
        for (int i = 0; data[i]; ++i) {
            if (data[i] == '(') {
                TreeNode *root = new TreeNode(stoi(str));
                if (!s.empty()) {
                    if (flag_r)  s.top()->right = root;
                    else  s.top()->left = root;
                } else  ans = root;
                s.push(root);
                flag_r = false;
                str = "";
            } else if (data[i] == ')') {
                s.pop();
            } else if (data[i] == ',') {
                flag_r = true;
                str = "";
            } else str += data[i];
        }
        return ans;
    }
};

// Your Codec object will be instantiated and called as such:
// Codec codec;
// codec.deserialize(codec.serialize(root));
   } else str += data[i];
        }
        return ans;
    }
};

// Your Codec object will be instantiated and called as such:
// Codec codec;
// codec.deserialize(codec.serialize(root));

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

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

相关文章

final域的内存语义

重排序规则 1. 在构造函数内对一个final域的写入&#xff0c;与随后把这个被构造对象引用赋值给一个引用变量&#xff0c;着两个操作不能重排序 2. 初次读一个包含final域的对象的引用&#xff0c;与随后初次读取这个final域&#xff0c;这两个操作不能重排序 以下面实例作说明…

基于ssm作业管理系统

随着计算机以及网络的普及&#xff0c;教师与学生对辅助教学方式的要求也越来越高&#xff0c;在教学辅助方式上追求质量及效率。作为教学核心组成之一的作业管理也趋向更加便 捷快速的方式。 经过调查&#xff0c;现阶段高校进行作业管理的方式主要有三种&#xff1a; 情况一&…

SSM学生宿舍管理系统(附源码)

本次介绍的是一个基于SSMJSP开发的学生宿舍管理系统的设计与实现&#xff0c;界面简洁、程序逻辑清晰&#xff0c;适合作为毕业设计的模板参考&#xff01; 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家 …

阿里妈妈star论文重点记录

论文地址&#xff1a;https://arxiv.org/pdf/2101.11427.pdf 1&#xff1a;业务实际应用 自 2020 年底以来&#xff0c;STAR 已部署在阿里巴巴展示广告系统&#xff0c;点击率提升8.0%和RPM增加6% 2&#xff1a;特点 星型拓扑促进跨多个domain的有效信息转换&#xff0c;在…

MATLB|抽水蓄能电站系统的最优竞价策略研究

&#x1f4a5;&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️❤️&#x1f4a5;&#x1f4a5;&#x1f4a5;&#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清…

Python自动化测试面试题——接口篇

目录 网络模型 OSI有哪几层,分别包含哪些协议? 协议 TCP,UDP的区别? TCP如何确保可靠传输? 三次握手与四次挥手? HTTP有哪些请求方法? HTTP常见的状态码有哪些? GET和POST的区别? Cookie和Session的区别? Token和Session的区别? HTTP和HTTPS的区别? 接口…

JavaScript(二):变量、数据类型、类型转换

变量一、变量的使用1.声明变量2.赋值3.变量的初始化4.变量的更新5.同时声明多个变量6.声明变量的特殊情况7.变量的命名规则二、数据类型数字型1.数字型Number2.数字型范围3.数字型的特殊值4.isNaA()字符串型String1.字符串型格式2.字符串型引号嵌套3.字符串转义符4.字符串长度5…

R语言相关分析和稳健线性回归分析

介绍 下面以物种多样性为例子展示了如何在R语言中进行相关分析和线性回归分析。 怎么做测试 相关和线性回归示例 Data read.table(textConnection(Input),headerTRUE) 数据简单图 plot(Species ~ Latitude, dataData, pch16,xlab "Latitude", ylab "Specie…

web前端期末大作业:体育网页主题网站设计——体育兵乓球5页面HTML+CSS+JavaScript

&#x1f389;精彩专栏推荐 &#x1f4ad;文末获取联系 ✍️ 作者简介: 一个热爱把逻辑思维转变为代码的技术博主 &#x1f482; 作者主页: 【主页——&#x1f680;获取更多优质源码】 &#x1f393; web前端期末大作业&#xff1a; 【&#x1f4da;毕设项目精品实战案例 (10…

ES运维常用指令,常用的故障诊断指令,es集群健康状况、集群节点分配信息、分片分配信息、分片未分配问题诊断、集群开启密码访问

目录 查询集群的健康状况 查看集群中所有节点的分配信息 查询集群/索引的文档总计数 查询集群的分片分配信息 查询集群中索引的分片数、文档数或集群中包含哪些索引 查询集群的快照存储信息 查看集群状态信息 查看集群统计信息 查看集群中所有节点的节点属性 查询分片…

javaScript 进阶之路 --- 《手写“回调地狱”》

前言&#xff1a; 可能初次看到这个标题&#xff0c;你会有些惊讶。我们不是要实现“手写 Promise ”吗&#xff1f;怎么变成了手写“回调地狱”了&#xff1f;“我老早看视频学习的时候就知道&#xff0c;我们要避免写成“回调地狱的格式&#xff0c;怎么到你这还要手写这玩意…

论文投稿指南——中国(中文EI)期刊推荐(第5期)

&#x1f680; EI是国际知名三大检索系统之一&#xff0c;在学术界的知名度和认可度仅次于SCI&#xff01;&#x1f384;&#x1f388; 【前言】 想发论文怎么办&#xff1f;手把手教你论文如何投稿&#xff01;那么&#xff0c;首先要搞懂投稿目标——论文期刊。其中&#xf…

智能优化算法:蜣螂优化算法-附代码

智能优化算法&#xff1a;蜣螂优化算法 摘要&#xff1a;蜣螂优化算法( Dung beetle optimizer, DBO), 是由 Jiankai Xue 等于2022 年提出的一种群体智能优化算法。其灵感来源于蜣螂的生物行为过程&#xff0c;具有寻优能力强&#xff0c;收敛速度快的特点。 1.蜣螂优化算法 …

一款很火的智能化 Shell 工具多色彩优化命令显示结果可以替换系统默认的 Shell 工具,支持多平台免费开源使用

一款很火的智能化 Shell 工具多色彩优化命令显示结果可以替换系统默认的 Shell 工具&#xff0c;支持多平台免费开源使用。 Nushell&#xff0c;它是用Rust写的&#xff0c;安全性提高的同时&#xff0c;Bug率也降低了&#xff0c;NuShell 专注于实现以下目标&#xff1a; 1、…

【云原生】Prometheus AlertManager讲解与实战操作

文章目录一、概述二、AlertManager 架构三、AlertManager 部署1&#xff09;下载2&#xff09;配置3&#xff09;启动服务4&#xff09;与Prometheus集成四、在Prometheus中设置告警规则五、AlertManager 告警通道配置一、概述 Prometheus 包含一个报警模块&#xff0c;就是我们…

利用图文和代码深度解析操作系统OS的内存管理实现原理机制和算法

利用图文和代码深度解析操作系统OS的内存管理实现原理机制和算法。 内存作为计算机系统的组成部分,跟开发人员的日常开发活动有着密切的联系,我们平时遇到的Segment Fault、OutOfMemory、Memory Leak、GC等都与它有关。本文所说的内存,指的是计算机系统中的主存(Main Memo…

LIFT: Learned Invariant Feature Transform详细笔记

LIFT: Learned Invariant Feature Transform Paper: LIFT: Learned Invariant Feature Transform | SpringerLink Code: GitHub - cvlab-epfl/LIFT: Code release for the ECCV 2016 paper 文章目录Abstract思路来源LIFT文献来源方法&#xff1a;LIFTPipeline网络架构训练流程…

【网络】网络基础

文章目录依据覆盖范围的网络分类初识网络协议网络协议分层OSI分层模型TCP/IP分层模型网络协议栈中每一层的典型协议和典型设备应用层传输层网络层数据链路层物理层初识IP地址和MAC地址IP地址MAC地址网络是数据传输的解决方案。计算机数量由少变多&#xff0c;计算机由单台机器完…

火爆全球的网红OpenAI ChatGPT注册教程

地址&#xff1a;https://chat.openai.com/ 1. 登陆上去体验 写代码问题 Could you help me to write a C function to upload a file to ASW S3?回复 带代码和注释 Sure, here is an example of how you might write a C function to upload a file to Amazon S3: #incl…

Redis Cluster高可用集群部署

​欢迎光临我的博客查看最新文章: https://river106.cn Redis从3.0开始支持Redis Cluster集群部署&#xff0c;在3.0之前使用哨兵模式来实现Redis集群&#xff08;利用Sentinel来监控master节点的状态&#xff0c;如果master节点异常&#xff0c;则将其中一台slave切换为master…