概念
什么叫序列化和反序列化?
其实,序列化和反序列化和所谓的持久化,都是差不多的概念。就是讲内存中的数据保存到外存上的过程。内存是断电既失的,而内存中的二叉树的数据结构,如何保存到外存上,就是二叉树的序列化,而二叉树的反序列化,就是将外存上保存的数据,再原封不动的还原回原来的二叉树。
思路
二叉树的序列化,一般有两大类方式,一种是用前序遍历、中序遍历、后序遍历的方式。另一种是层序遍历的方式。其实就是对应底层是用递归(栈)来实现,还是用队列来实现。
前序遍历序列化
外存上一般都是用Json或者就是一般的字符串来保存数据,因此,前序遍历序列化过程,就是把前序遍历输出节点的时候,把该输出的值拼接到字符串上。要格外注意叶子节点,叶子节点的左右孩都为空,要全部记录到字符串中,不能因为是null在就不记录,也要占位,不然,就会造成混乱。可以自己设定一套规则,比如为空时,我用#_代替,不为空的节点用value_表示。
前序遍历一遍后,就会输出一个长字符串。
比如,前序遍历1、2、3。最终输出的字符串为:1_2_#_#_3_#_#_
序列化代码:
递归实现
public static String serialByPre(TreeNode node){
if(node==null){
return"#_";
}
String str=node.value+"_";
str += serialByPre(node.left);
str += serialByPre(node.right);
return str;
}
反序列化过程,其实还是用递归再跑一遍,把前面生成字符串的过程,再还原出来,生成二叉树节点,并链接起来。
反序列化代码:
public static TreeNode reconByPreString(String string){
String[] s = string.split("_");
Queue<String> queue=new LinkedList<String>();
for (int i = 0; i < s.length; i++) {
queue.add(s[i]);
}
return reconPreOrder(queue);
}
private static TreeNode reconPreOrder(Queue<String> queue) {
String poll = queue.poll();
if(poll.equals("#")){
return null;
}
TreeNode node=new TreeNode(Integer.parseInt(poll));
node.left=reconPreOrder(queue);
node.right=reconPreOrder(queue);
return node;
}
有了前序遍历,其实中序遍历和后序遍历都是一样的。类比二叉树递归实现的前序中序后序遍历过程,只不过是打印的位置变一下而已,其他都一样,序列化反序列化也是一样。