当前位置:网站首页>前序、后序及层次遍历实现二叉树的序列化与反序列化
前序、后序及层次遍历实现二叉树的序列化与反序列化
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了:二叉树的序列化与反序列化
边栏推荐
猜你喜欢
随机推荐
The future of the hybrid interface: conversational UI
来n遍剑指--09. 用两个栈实现队列
Build finished with errors/Executable Not Found
Scala basics [seq, set, map, tuple, WordCount, queue, parallel]
Come n times with the sword--05. Replace spaces
Mybaits 常用问题详解
如何将虚拟机上的文件复制到主机上
第七章
Implement a thread pool
ReentrantLock
如何在 TiDB Cloud 上使用 Databricks 进行数据分析 | TiDB Cloud 使用指南
(C language) program environment and preprocessing
Linux 创建mysql数据库并创建账号密码
Module eight
matlab常用符号用法总结
js部门预算和支出雷达图
【NLP】Transformer理论解读
【Excel】生成随机数字/字符
Flink1.15 source code reading flink-clients - flink command line help command
Redis Cluster - Sentinel Mode Principle (Sentinel)









