剑指 Offer 37. 序列化二叉树
请实现两个函数,分别用来序列化和反序列化二叉树。
你需要设计一个算法来实现二叉树的序列化与反序列化。这里不限定你的序列 / 反序列化算法执行逻辑,你只需要保证一个二叉树可以被序列化为一个字符串并且将这个字符串反序列化为原始的树结构。
提示:输入输出格式与 LeetCode 目前使用的方式一致,详情请参阅 LeetCode 序列化二叉树的格式。你并非必须采取这种方式,你也可以采用其他的方法解决这个问题。
思路:使用先进先出的队列完成二叉树的按层遍历BFS。
在下面的序列化、反序列化函数中,为了保持一致性,规定:只有当结点不为null时,才允许进入队列queue。
/**
* 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) {
ArrayList<String> ans = new ArrayList<>();
Queue<TreeNode> queue = new LinkedList<>();
if(root!=null){// 这样省去了“讨论root为null”的麻烦
queue.offer(root);
ans.add(String.valueOf(root.val));
}
while(!queue.isEmpty()){
TreeNode cur = queue.poll();
if(cur.left!=null){
queue.offer(cur.left);
ans.add(String.valueOf(cur.left.val));
}else{
ans.add("null");
}
if(cur.right!=null){
queue.offer(cur.right);
ans.add(String.valueOf(cur.right.val));
}else{
ans.add("null");
}
}
int i=0,index=0;
for(String s:ans){
if(!s.equals("null")){
index=i;
}
i++;
}
StringBuilder builder = new StringBuilder();
builder.append("[");
if(ans.size()==0){
return builder.append("]").toString();
}
builder.append(ans.get(0));
for(i=1;i<=index;i++){
builder.append(","+ans.get(i));
}
builder.append("]");
return builder.toString();
}
// Decodes your encoded data to tree.
public TreeNode deserialize(String data) {
if(data.substring(1,data.length()-1)==""){
return null;
}
String[] strs = data.substring(1,data.length()-1).split(",");
Queue<TreeNode> queue = new LinkedList<>();
TreeNode root = new TreeNode(Integer.parseInt(strs[0]));
queue.offer(root);
int index=0;
while(!queue.isEmpty()){
TreeNode cur = queue.poll();
if(index+1<strs.length&&!strs[++index].equals("null")){
cur.left = new TreeNode(Integer.parseInt(strs[index]));
queue.offer(cur.left);
}
if(index+1<strs.length&&!strs[++index].equals("null")){
cur.right = new TreeNode(Integer.parseInt(strs[index]));
queue.offer(cur.right);
}
}
return root;
}
}
// Your Codec object will be instantiated and called as such:
// Codec codec = new Codec();
// codec.deserialize(codec.serialize(root));