序列化二叉树
不同于把字符串变成二叉树,序列化是把二叉树变成字符串,使用前序遍历,用1个特殊字符表示空,然后递归实现。
实现过程就是利用一个StringBuilder来拼接字符串,将sb和头结点传入递归函数中,正常前序遍历,在处理节点的时候,将它的值加一个节点结束符!拼接到sb中,递归拼接。最后返回sb。在原函数中返回sb.toStirng
String Serialize(TreeNode root) {
if(root==null){
return "#!";
}
StringBuilder sb=new StringBuilder();
core1(root,sb);
return sb.toString();
}
void core1(TreeNode root,StringBuilder sb){
if(root==null){
sb.append("#!");
return;
}
sb.append(root.val);
sb.append("!");
core1(root.left,sb);
core1(root.right,sb);
}
反序列化二叉树
因为知道的是前序遍历字符串,所以读到的第一个就是头结点,先利用!来将字符串分割成strs,将其传入递归函数中,在外设置一个i来表示字符串的index,为什么要在外,因为在内的话递归回来i的值无法保存。令i为0,进来之后就根据值来创建树节点。接着令i++,递归传入strs,返回的就是左子树。此时i应该是跟着同步加完的,所以直接传入右子树。递归返回条件要注意是为#,此时要让i++,因为如果不加返回的左子树就直接进右子树了,没有i的推进。
TreeNode Deserialize(String str) {
if(str==null || str.length()==0){
return null;
}
String[] s=str.split("!");
return core2(s);
}
int i=0;//为什么要设置一个全局变量i,因为所有的递归都是基于i的值,而如果传参的话返回来的时候i就不是变了的值了。
TreeNode core2(String[] strs){
if(strs[i].equals("#")){
i++;//这里i++是因为只有进左节点的时候i加了一次,如果发现为null退出去则直接会进入right,就不会i++了,为了保证i的推进
return null;
}
TreeNode node=new TreeNode(Integer.parseInt(strs[i]));
i++;
node.left=core2(strs);
node.right=core2(strs);
return node;
}