当前位置:网站首页>前序、后序及层次遍历实现二叉树的序列化与反序列化
前序、后序及层次遍历实现二叉树的序列化与反序列化
2022-07-31 09:51:00 【b17a】
本文将实现两个方法,一个是序列化方法,定义如下,
public String serialize(TreeNode root) {
}
语义:传入一颗二叉树,以字符串的形式返回它的序列化结果。
另一个是反序列化方法,定义如下,
public TreeNode deserialize(String data) {
}
语义:传入之前的序列化结果,还原出这颗二叉树。
树节点定义如下,
class TreeNode {
int val;
TreeNode left;
TreeNode right;
TreeNode(int x) {
val = x; }
}
下面分别使用二叉树树的前序遍历、后续遍历以及层次遍历进行序列化与反序列化。
二叉树的各种遍历方式及其递归与非递归的实现可参考这篇文章:
https://blog.csdn.net/weixin_45685353/article/details/106694041
前序
序列化方法需额外引入一个实现二叉树前序遍历的方法,其整体实现如下,
public String serialize(TreeNode root) {
StringBuilder sb = new StringBuilder();
pre(root, sb);
return sb.toString();
}
private void pre(TreeNode root, StringBuilder sb) {
if (root == null) {
sb.append("#,");
return;
}
sb.append(root.val).append(",");
pre(root.left, sb);
pre(root.right, sb);
}
其反序列化方法也许借助额外的方法,因为序列化的结果形如[根节点,左节点,右节点],因此,反序列化的时候也是按照这个顺序重构就好,实现如下,
int i;// 全局变量,表示数组下标
public TreeNode deserialize(String data) {
i = 0;// 从头开始
return pre(data.split(","));
}
private TreeNode pre(String[] s) {
if ("#".equals(s[i])) {
return null;
}
TreeNode root = new TreeNode(Integer.parseInt(s[i]));
i++;
root.left = pre(s);
i++;
root.right = pre(s);
return root;
}
后序
后序遍历的序列化实现跟前序遍历差不多,改变下位置即可,如下,
public String serialize(TreeNode root) {
StringBuilder sb = new StringBuilder();
post(root, sb);
return sb.toString();
}
private void post(TreeNode root, StringBuilder sb) {
if (root == null) {
sb.append("#,");
return;
}
post(root.left, sb);
post(root.right, sb);
sb.append(root.val).append(",");
}
其反序列化也差不多,因为其序列化结果形如[左节点,右节点,根节点],因此我们在反序列化的时候,从尾部开始,即先构造根节点,再构造右节点,最后左节点,代码如下,
int i;// 全局变量,表示数组下标
public TreeNode deserialize(String data) {
String[] s = data.split(",");
i = s.length - 1;// 从尾部开始
return post(s);
}
private TreeNode post(String[] s) {
if ("#".equals(s[i])) {
return null;
}
TreeNode root = new TreeNode(Integer.parseInt(s[i]));
i--;
root.right = post(s);
i--;
root.left = post(s);
return root;
}
层次
借助队列这种数据结构,实现对二叉树的层次遍历,空节点用’#‘表示,用’,'作为分隔符,其序列化方法的实现如下,
public String serialize(TreeNode root) {
StringBuilder sb = new StringBuilder();
LinkedList<TreeNode> queue = new LinkedList<>();
queue.addLast(root);
while (!queue.isEmpty()) {
root = queue.removeFirst();
if (root == null) {
sb.append("#");
} else {
sb.append(root.val);
queue.addLast(root.left);
queue.addLast(root.right);
}
sb.append(",");
}
return sb.toString();
}
其反序列化方法的实现如下,
public TreeNode deserialize(String data) {
String[] s = data.split(",");
if ("#".equals(s[0])) return null;
TreeNode root = new TreeNode(Integer.parseInt(s[0])), p = root;
int i = 1;
LinkedList<TreeNode> queue = new LinkedList<>();
queue.addLast(p);
while (i < s.length) {
p = queue.removeFirst();
if (!"#".equals(s[i])) {
p.left = new TreeNode(Integer.parseInt(s[i]));
queue.addLast(p.left);
}
if (i + 1 < s.length && !"#".equals(s[i + 1])) {
p.right = new TreeNode(Integer.parseInt(s[i + 1]));
queue.addLast(p.right);
}
i += 2;
}
return root;
}
看完本篇文章,随便可以把力扣的这道题给AC了:二叉树的序列化与反序列化
边栏推荐
- 作为面试官,关于线程池的问题我一般这样套路...
- 富文本编辑器Tinymce
- Data Middle Office Construction (6): Data System Construction
- 项目管理工具之燃尽图:动态考核团队工作能力
- 第二十四课、二十五课,高级光照(blinn),Gamma矫正
- 【机器学习】用特征量重要度(feature importance)解释模型靠谱么?怎么才能算出更靠谱的重要度?
- Chapter VII
- 如何将虚拟机上的文件复制到主机上
- 踩水坑2 数据超出long long
- Emotional crisis, my friend's online dating girlfriend wants to break up with him, ask me what to do
猜你喜欢
随机推荐
Mybaits 常用问题详解
Echart饼图添加轮播效果
GVINS论文阅读笔记
第二十四课、二十五课,高级光照(blinn),Gamma矫正
Emotional crisis, my friend's online dating girlfriend wants to break up with him, ask me what to do
Progressive Web App(PWA)
loadrunner-controller-手动场景Schedule配置
浏览器使用占比js雷达图
Scala基础【seq、set、map、元组、WordCount、队列、并行】
Redis Sentinel原理
What is the encoding that starts with ?
Come n times - 06. Print the linked list from end to end
浓眉大眼的谷歌 Chrome 也叛变了,教你一招快速清除其自带广告
js滚动条滚动到指定元素
【微信小程序开发】生命周期与生命周期函数
Kotlin—基本语法(二)
Flink1.15 source code reading - PER_JOB vs APPLICATION execution process
优信年营收16亿:亏损3亿 已与蔚来资本及58集团签署股权协议
如何在 TiDB Cloud 上使用 Databricks 进行数据分析 | TiDB Cloud 使用指南
loadrunner-controller-场景执行run