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了:二叉树的序列化与反序列化