当前位置:网站首页>前序、后序及层次遍历实现二叉树的序列化与反序列化
前序、后序及层次遍历实现二叉树的序列化与反序列化
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了:二叉树的序列化与反序列化
边栏推荐
- Flink1.15 source code reading flink-clients - flink command line help command
- vue element form表单规则校验 点击提交后直接报数据库错误,没有显示错误信息
- (C语言)程序环境和预处理
- Use turtle to draw buttons
- 比较并交换 (CAS) 原理
- Dart Log tool class
- 第六章
- Are postgresql range queries faster than index queries?
- Linux 创建mysql数据库并创建账号密码
- 7. JS ES6新增语法 new Map详讲,还有一道代码实战案例帮你快上手new Map
猜你喜欢
随机推荐
Echart饼图添加轮播效果
VMware下安装win10
浏览器使用占比js雷达图
js implements the 2020 New Year's Day countdown bulletin board
如何将亚马逊广告添加到您的 WordPress 网站(3 种方法)
canvas粒子变幻各种形状js特效
我们能做出来数据库吗?
出色的移动端用户验证
【机器学习】用特征量重要度(feature importance)解释模型靠谱么?怎么才能算出更靠谱的重要度?
Use turtle to draw buttons
Come n times with the sword--05. Replace spaces
js实现2020年元旦倒计时公告牌
开放麒麟 openKylin 自动化开发者平台正式发布
作为面试官,关于线程池的问题我一般这样套路...
js department budget and expenditure radar chart
富文本编辑器Tinymce
【NLP】Transformer理论解读
postgresql generate random date, random time
js部门预算和支出雷达图
Linux 创建mysql数据库并创建账号密码