一 题目:序列化二叉树
二叉树的序列化是指:把一棵二叉树按照某种遍历方式的结果以某种格式保存为字符串,从而使得内存中建立起来的二叉树可以持久保存。序列化可以基于先序、中序、后序、层序的二叉树遍历方式来进行修改,序列化的结果是一个字符串,序列化时通过 某种符号表示空节点(#)。
二叉树的反序列化是指:根据某种遍历顺序得到的序列化字符串结果str,重构二叉树。
二 思路分析
1 序列化
-
可以使用前序遍历来将节点保存到字符串中,但是为了反序列化,需要以满二叉树的方式保存,那么没有的地方我们就用"#"来表示!
-
分为多种情况,
-
情形一:该节点没有子节点
此时,返回的字符串为:“节点的value, #, #”
-
情形二:该节点只有一个左子节点
返回的字符串为:“节点的value,节点的左子节点的value, #”
-
情形三:该节点只有一个右子节点
返回的字符串为:“节点的value,#, 节点的右子节点的value”
-
-
递归的方法。不用去追究每次递归的细节,只需要关注总问题和子问题之间的关系即可。如下代码所示内容,因为不管是总问题还是子问题,都需要将结果保存到字符串中,那么这里就巧妙的使用了StringBuilder(),将子问题遍历的结果保存到字符串中,然后再使用StringBuilder的ad方法,添加到总问题中。就是这样简单!
-
代码如下:
public String Serialize(TreeNode root) {
StringBuilder sb = new StringBuilder();
if (root == null) {
// 递归终止条件内容
sb.append("#,");
return sb.toString();
}
sb.append(root.val + ",");
sb.append(Serialize(root.left));
sb.append(Serialize(root.right));
return sb.toString(); // 方法执行结束时的返回的内容!
}
经过上述步骤后,字符串中保存的是:"1,2,#,3,#,#,4,5,#,#,#,"
2 反序列化
-
假设只存在一个结点和其左右两个子节点内容,那么很简单内可以使用一下代码搞定
node = new TreeNode(str[0]) node.left = new TreeNode(str[1]) node.right = new TreeNode(str[2])
-
但是现在并不是一个简单的二叉树,并且字符串中还包含其他的内容,尝试用递归的方法来解决这个问题。首先用index来索引字符,然后还有判断是否为"#",具体过程如下
- 先从1开始,创建一个root节点
- 根节点的左子节点,通过遍历第二个字符来获取
- 根节点的右子节点,等到左子树遍历完了之后,在根据index来获取
- 总问题和子问题之间,我们使用返回的节点来连接。
具体代码如下:
public TreeNode Deserialize(String str) { index++; //每次调用方法,index自增1 String[] strr = str.split(","); TreeNode node = null; if (!strr[index].equals("#")) { node = new TreeNode(Integer.valueOf(strr[index])); node.left = Deserialize(str); node.right = Deserialize(str); } return node; //最后返回的是根节点的内容 }
三 代码实现
public class Solution43 {
int index = -1; // 计数变量
public String Serialize(TreeNode root) {
StringBuilder sb = new StringBuilder();
if (root == null) {
sb.append("#,");
return sb.toString();
}
sb.append(root.val + ",");
sb.append(Serialize(root.left));
sb.append(Serialize(root.right));
return sb.toString();
}
public TreeNode Deserialize(String str) {
index++;
String[] strr = str.split(",");
TreeNode node = null;
if (!strr[index].equals("#")) {
node = new TreeNode(Integer.valueOf(strr[index]));
node.left = Deserialize(str);
node.right = Deserialize(str);
}
return node;
}
}