《剑指 Offer》专项突破版 - 面试题 48 : 序列化和反序列化二叉树(C++ 实现)

目录

前言

一、序列化二叉树

二、反序列化二叉树


 


前言

题目链接:LCR 048. 二叉树的序列化与反序列化 - 力扣(LeetCode)

题目

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


一、序列化二叉树

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

实际上,只是把节点的值序列化到字符串中是不够的

  1. 首先,要用一个分隔符(如逗号)把不同的节点分隔开

  2. 其次,还有考虑如何才能在反序列化的时候构造不同结构的二叉树。例如,下图 (a) 和下图 (b) 中的二叉树都有 5 个节点,并且每个节点的值都是 6。如果只把节点的值序列化到字符串,那么序列化这两棵二叉树的结果将是相同的。如果这样,反序列化的时候就不能构建不同结构的二叉树。

    应该如何区分上图 (a) 和上图 (b) 中的两棵二叉树?上图 (a) 中二叉树的第 2 层第 2 个节点的两个子节点均为 nullptr,而上图 (b) 中二叉树的第 2 层第 1 个节点的两个子节点均为 nullptr。也就是说,尽管 nullptr 节点通常没有在图上画出来,但它们对树的结构是至关重要的。因此,应该把 nullptr 节点序列化成一个特殊的字符串。如果把 nullptr 节点序列化成 "#",那么上图 (a) 中的二叉树用前序遍历将被序列化成字符串 "6,6,6,#,#6,#,#,6,#,#",而上图 (b) 中的二叉树将被序列化成字符串 "6,6,#,#,6,6,#,#,6,#,#"。

序列化二叉树的参考代码如下所示:

string serialize(TreeNode* root)
{if (root == nullptr)return "#";return to_string(root->val) + ","+ serialize(root->left) + ","+ serialize(root->right);
}


二、反序列化二叉树

接着考虑反序列化。由于把二叉树序列化成一个以逗号作为分隔符的字符串,因此可以根据分隔符把字符串分隔成若干子字符串,每个子字符串对应二叉树的一个节点。如果一个节点为 nullptr,那么它和 "#" 对应;否则这个节点将和一个表示它的值的子字符串对应

如果用前序遍历序列化二叉树,那么分隔后的第 1 个字符串对应的就是二叉树的根节点,因此可以先根据这个字符串构建出二叉树的根节点,然后先后反序列化二叉树的左子树和右子树。在反序列化它的左子树和右子树时可以采用类似的方法,也就是说,可以调用递归函数解决反序列化子树的问题

递归地反序列化二叉树的参考代码如下所示:

TreeNode* CreateBiTree(const vector<string>& v, int* pi)
{if (v[*pi] == "#"){++(*pi);return nullptr;}TreeNode* root = new TreeNode(stoi(v[(*pi)++]));root->left = CreateBiTree(v, pi);root->right = CreateBiTree(v, pi);return root;
}
​
TreeNode* deserialize(string data)
{vector<string> v;size_t pos = 0;size_t ret;while ((ret = data.find(",", pos)) != string::npos){v.push_back(data.substr(pos, ret - pos));pos = ret + 1;}v.push_back(data.substr(pos));
​int i = 0;return CreateBiTree(v, &i);
}

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Python二级考试笔记

Python二级考试笔记【源源老师】 01. 字符串 1. 常规功能合集 字符串本身有一些功能&#xff0c;有些之前运用过&#xff0c;这里总结如下&#xff1a; # 功能一&#xff1a;判断字符串类型 print(type("Hello")) print(str(123)) # 转换# 功能二&#xff1a;连…

c入门第十八篇——支持学生数的动态增长(链表,指针的典型应用)

数组最大的问题&#xff0c;就是不支持动态的扩缩容&#xff0c;它是静态内存分配的&#xff0c;一旦分配完成&#xff0c;其容量是固定的。为了支持学生的动态增长&#xff0c;这里可以引入链表。 链表 在C语言中&#xff0c;链表是一种常用的数据结构&#xff0c;它由一系列…

“分布式透明化”在杭州银行核心系统上线之思考

导读 随着金融行业数字化转型的需求&#xff0c;银行核心系统的升级改造成为重要议题。杭州银行成功上线以 TiDB 为底层数据库的新一代核心业务系统&#xff0c;该实践采用应用与基础设施解耦、分布式透明化的设计开发理念&#xff0c;推动银行核心系统的整体升级。 本文聚焦…

C语言从零实现贪吃蛇小游戏

制作不易&#xff0c;点赞关注一下呗&#xff01;&#xff01;&#xff01; 文章目录 前言一. 技术要点二、WIN32API介绍三、贪吃蛇游戏设计与分析 1.游戏开始前的初始化 2.游戏运行的逻辑 总结 前言 当我们掌握链表这样的数据结构之后&#xff0c;我们就可以用它来…

【数据结构】16 二叉树的定义,性质,存储结构(以及先序、后序、中序遍历)

二叉树 一个二叉树是一个有穷的结点集合。 它是由根节点和称为其左子树和右子树的两个不相交的二叉树组成的。 二叉树可具有以下5种形态。 性质 一个二叉树第i层的最大结点数为 2 i − 1 2^{i-1} 2i−1, i ≥ 1 i \geq 1 i≥1 每层最大结点可以对应完美二叉树&#xff08;…

Linux:docker搭建redis集群(3主3从扩容缩容 哈希槽分配)

操作系统&#xff1a;centos7 docker-ce版本&#xff1a;24.0.7 1.准备redis镜像 我这里使用redis 6.0.8 镜像进行操作&#xff0c;如果你也需要镜像&#xff0c;在网络正常情况下直接使用 docker pull redis:6.0.8 即可进行下载&#xff0c;如果你没配置国内加速器&#x…

相机图像质量研究(22)常见问题总结:CMOS期间对成像的影响--光学串扰

系列文章目录 相机图像质量研究(1)Camera成像流程介绍 相机图像质量研究(2)ISP专用平台调优介绍 相机图像质量研究(3)图像质量测试介绍 相机图像质量研究(4)常见问题总结&#xff1a;光学结构对成像的影响--焦距 相机图像质量研究(5)常见问题总结&#xff1a;光学结构对成…

机器人专题:我国机器人产业园区发展现状、问题、经验及建议

今天分享的是机器人系列深度研究报告&#xff1a;《机器人专题&#xff1a;我国机器人产业园区发展现状、问题、经验及建议》。 &#xff08;报告出品方&#xff1a;赛迪研究院&#xff09; 报告共计&#xff1a;26页 机器人作为推动工业化发展和数字中国建设的重要工具&…

LEETCODE 69. x 的平方根

class Solution { public:int mySqrt(int x) {int left0;int rightx;int midleft(right-left)/2;int ans-1;while(left<right){midleft(right-left)/2;if((long long)mid*mid<x){ansmid;leftmid1;}else{rightmid-1;}}return ans;} };*(long long)

js示例1(图片轮播)

<!DOCTYPE html> <html><head><meta charset"utf-8"><title>图片轮播</title><style>#box{ /*给图片盒子创建样式*/ width : 400px;height : 400px; margin: 0 auto; position: rela…

Qlik Sense : 条形图

条形图 “条形图适合比较多个值。维度轴显示所比较的类别条目&#xff0c;度量轴显示每个类别条目的值。” Qlik Sense中的条形图是一种数据可视化工具&#xff0c;用于展示不同类别或维度之间的比较。它通过水平或垂直的条形表示数据&#xff0c;并根据数值的大小进行排序。…

JavaWeb之Servlet接口

Servlet接口 什么是Servlet&#xff1f; Servlet是一种基于Java技术的Web组件&#xff0c;用于生成动态内容&#xff0c;由容器管理&#xff0c;是平台无关的Java类组成&#xff0c;并且由Java Web服务器加载执行&#xff0c;是Web容器的最基本组成单元 什么是Servlet容器&…