题目:请实现两个函数,分别用来序列化和反序列化二叉树
二叉树的序列化是指:把一棵二叉树按照某种遍历方式的结果以某种格式保存为字符串,从而使得内存中建立起来的二叉树可以持久保存。序列化可以基于先序、中序、后序、层序的二叉树遍历方式来进行修改,序列化的结果是一个字符串,序列化时通过 某种符号表示空节点(#),以 ! 表示一个结点值的结束(value!)。
二叉树的反序列化是指:根据某种遍历顺序得到的序列化字符串结果str,重构二叉树。
链接:https://www.nowcoder.com/practice/cf7e25aa97c04cc1a68c8f040e71fb84
先序遍历思路:
先序遍历是先遍历根节点。再遍历左子树,再遍历右子树;左子树、右子树的遍历一样,典型的递归思路。
/*
public class TreeNode {
int val = 0;
TreeNode left = null;
TreeNode right = null;
public TreeNode(int val) {
this.val = val;
}
}
*/
public class Solution {
String Serialize(TreeNode root) {
// 如果传进来的是个空节点,则返回#!(以 ! 表示一个结点值的结束)
if(root==null) return "#!";
StringBuilder sb = new StringBuilder();
// 先添加根节点的值
sb.append(root.val).append("!");
// 然后再添加 左子树序列化后的字符串
sb.append(Serialize(root.left));
// 最后添加 右子树序列化后的字符串
sb.append(Serialize(root.right));
return sb.toString();
}
int start = 0; // 用于标识当前反序列化的字符下标
TreeNode Deserialize(String str) {
if(str==null || str.length()==0) return null;
return deserialize(str.split("!"));
}
TreeNode deserialize(String[] str){
// 如果下标超出数组大小,说明反序列化完成
if(start >= str.length) return null;
// 如果当前反序列化的字符是#,说明是空节点
if(str[start].equals("#")) return null;
// 将字符转成节点
int val = Integer.valueOf(str[start]);
TreeNode node = new TreeNode(val);
// 反序列化左子树
++start;
node.left = deserialize(str);
// 反序列化右子树(这一步可以看出start声明成全局的作用是为了确定右子树根节点的下标,不是简单的start+2)
++start;
node.right = deserialize(str);
return node;
}
}
后序遍历和先序遍历差不多,只是反序列化的时候从字符串尾端开始:
String Serialize(TreeNode root){
if(root==null) return "#!";
StringBuilder sb = new StringBuilder();
sb.append(Serialize(root.left));
sb.append(Serialize(root.right));
sb.append(root.val).append("!");
return sb.toString();
}
int start = 0;
TreeNode Deserialize(String str) {
if(str==null || str.length()==0) return null;
start = str.split("!").length-1;
return deserialize(str.split("!"));
}
TreeNode deserialize(String[] str){
if(start < 0 || str[start].equals("#")){
return null;
}else{
int val = Integer.valueOf(str[start]);
TreeNode node = new TreeNode(val);
--start;
node.right = deserialize(str);
--start;
node.left = deserialize(str);
return node;
}
}
层序:
String Serialize(TreeNode root){
if(root==null) return "#!";
Queue<TreeNode> queue = new LinkedList<>();
queue.offer(root);
StringBuilder sb = new StringBuilder();
while(!queue.isEmpty()){
TreeNode node = queue.poll();
if(node!=null){
sb.append(node.val).append("!");
queue.offer(node.left);
queue.offer(node.right);
}else{
sb.append("#!");
}
}
return sb.toString();
}
TreeNode Deserialize(String str) {
if(str==null || str.length()==0) return null;
String[] strs = str.split("!");
TreeNode[] nodes = new TreeNode[strs.length];
for(int i=0; i<strs.length; ++i){
if(!strs[i].equals("#")){
nodes[i]= new TreeNode(Integer.valueOf(strs[i]));
}
}
for(int i=0,j=1; i<strs.length; ++i){
if(nodes[i]!=null){
nodes[i].left = nodes[j++];
nodes[i].right = nodes[j++];
}
}
return nodes[0];
}