思路:因为可以使用'#'表示空结点,先序遍历就足够了;如果不能使用空结点符号,需要同时使用先序遍历和中序遍历;
序列化思路:直接递归即可,要注意'!'分隔符的添加,不要重复;
反序列化思路:
字符串的第一个结点是根结点,第二个结点是左子树根结点,必须将左子树全部构建完成才可以构建右子树,因此每构建一个结点连接到树上,需要将该结点的字符从字符串前段删除,该过程使用递归解决;
当左子树构建完毕,剩余的字符串就是右子树,递归即可。
序列化代码:
public String Serialize(TreeNode root) {
if(root==null) return "#";
String answerList=""+root.val;
String leftList=Serialize(root.left);
String rightList=Serialize(root.right);
//避免分隔符添加错误
if(answerList.charAt(answerList.length()-1)!='!'){
answerList=answerList+"!";
}
answerList=answerList+leftList;
if(answerList.charAt(answerList.length()-1)!='!'){
answerList=answerList+"!";
}
answerList=answerList+rightList;
if(answerList.charAt(answerList.length()-1)!='!'){
answerList=answerList+"!";
}
return answerList;
}
反序列化代码:
public TreeNode DeserializeCore(StringBuffer tmpStr) {
if(tmpStr==null||tmpStr.length()==0) {
return null;
}
//分离出当前根结点的值
String node=tmpStr.substring(0,tmpStr.indexOf("!"));
TreeNode root=null;
if(!node.equals("#")) {
root=new TreeNode(Integer.parseInt(node));
}
//将根结点从字符串前段去除
tmpStr.delete(0,tmpStr.indexOf("!")+1);
if(root!=null) {
//继续构造根结点的左子树
root.left=DeserializeCore(tmpStr);
//根结点的左子树构造完成后,构造右子树
root.right=DeserializeCore(tmpStr);
}
//左右子树构造完成,返回上一层父节点
return root;
}
public TreeNode Deserialize(String str) {
if(str==null||str.length()==0||str.equals("#")) return null;
StringBuffer tmpStr=new StringBuffer(str);
return DeserializeCore(tmpStr);
}