【leetcode-树】二叉树的序列化与反序列化
序列化是将一个数据结构或者对象转换为连续的比特位的操作,进而可以将转换后的数据存储在一个文件或者内存中,同时也可以通过网络传输到另一个计算机环境,采取相反方式重构得到原数据。
请设计一个算法来实现二叉树的序列化与反序列化。这里不限定你的序列 / 反序列化算法执行逻辑,你只需要保证一个二叉树可以被序列化为一个字符串并且将这个字符串反序列化为原始的树结构。
示例:
你可以将以下二叉树:
1
/
2 3
/
4 5
序列化为
"[1,2,3,null,null,4,5]"
提示: 这与 LeetCode 目前使用的方式一致,详情请参阅 LeetCode 序列化二叉树的格式。你并非必须采取这种方式,你也可以采用其他的方法解决这个问题。
说明: 不要使用类的成员 / 全局 / 静态变量来存储状态,你的序列化和反序列化算法应该是无状态的。
思路:
按照题中给的示例序列化采取的层次遍历,所以我们序列化也采取层次遍历,反序列化也设计成逆层次遍历构造。(当然你也可以使用其他遍历方式)(因为题目要求不能使用类的成员/全局等变量,所以递归方法实现构造比较困难。)
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
public class Codec {
// Encodes a tree to a single string.
public String serialize(TreeNode root) {
//层次遍历
StringBuilder stb = new StringBuilder();
stb.append("[");
Queue queue = new LinkedList<>();
queue.add(root);
while (!queue.isEmpty()) {
TreeNode treeNode = queue.poll();
if(treeNode==null) {
stb.append("null,");
continue;
}else {
stb.append(treeNode.val).append(",");
//不管左右子树是否为空,都需要入队列
queue.add(treeNode.left);
queue.add(treeNode.right);
}
}
/** 示例给出的序列化字符串为"[1,2,3,null,null,4,5]"
而按照上面的层次遍历得到的结果是"[1,2,3,null,null,4,5,null,null,null,null,"
因为当访问到最底层的节点时,左右子树不管都为空,任然会进入队列。*/
String result = stb.toString();
if(result.equals("[null,")) {
//如果是空树,去掉后面的逗号就可以
result = result.substring(0, result.length()-1);
}else {
//去掉最后多余的null,
int endIndex = result.length()-1;
while (result.charAt(endIndex)<'0' || result.charAt(endIndex)>'9') {
endIndex--;
}
result = result.substring(0, endIndex+1);
}
return result+="]";
}
// Decodes your encoded data to tree.
public TreeNode deserialize(String data) {
String[] strs = data.split(",");
//去掉第0个中的[ 和最后一个的]
int size = strs.length;
strs[0]=strs[0].substring(1, strs[0].length());
strs[size-1]=strs[size-1].substring(0, strs[size-1].length()-1);
if(strs[0].equals("null")) {
return null;
}
Queue queue = new LinkedList<>();
TreeNode root = new TreeNode(Integer.valueOf(strs[0]));
queue.add(root);
for(int i=1;i