序列化的定义:序列化是指将数据结构或对象状态转换为可访问的格式(例如将其保存为文件、存储在缓冲区中或通过网络发送),留给后续在同一个或另一个计算机环境中恢复原状的过程。当以序列化形式检索字节结果时,可以利用这一点来生成与原始对象具有相同语义的副本。从字节序列中提取数据结构的逆向操作是反序列化。前序模式下的序列化和反序列化1.前序模式下的序列化按照前序遍历的方法,二叉树的每个节点都存储为一个字符串,用指定的分隔符分隔,空节点也需要存储。/***预购模式序列化**@authorJava和算法学习:周一*/publicstaticQueuepreSerial(Nodehead){Queueans=newLinkedList<>();前(头,答案);returnans;}privatestaticvoidpre(Nodehead,Queueans){if(head==null){ans.add(null);}else{ans.add(String.valueOf(head.value));pre(head.left,ans);pre(head.right,ans);,恢复到原来的二叉树。/***前序反序列化**@authorJava和算法学习:周一*/publicstaticNodebuildByPre(Queuequeue){if(queue==null||queue.size()==0){returnnull;}returnpreB(queue);}privatestaticNodepreB(Queuequeue){Stringvalue=queue.poll();如果(值==null){返回null;head=newNodeNode(Integer.parseInt(value));head.left=preB(queue);head.right=preB(queue);returnhead;}??后序模式序列化和反序列化1.后序模式序列化和反序列化序列化和预序的思路和过程是一样的。需要注意的是,在反序列化的时候,一定要先把原来的序列化顺序倒过来(倒过来的顺序是headrightleft),然后按照headrightleft的方式反序列化,因为先有head再有children(构造headerfirst构造child),所以反序列化的结果是正确的。/***后序序列化**@authorJava和算法学习:星期一*/publicstaticQueueposSerial(Nodehead){Queueans=newLinkedList<>();pos(头,ans);返回ans;}publicstaticvoidpos(Nodehead,Queueans){if(head==null){ans.add(null);}else{pos(head.left,ans);pos(head.right,ans);ans.add(String.valueOf(head.value));}}/***后序反序列化**@authorJava与算法学习:周一*/publicstaticNodebuildByPos(Queuequeue){if(queue==null||queue.size()==0){返回空值;}Stackstack=newStack<>();while(!queue.isEmpty()){stack.push(queue.poll());}returnposB(stack);}publicstaticNodeposB(StackposStack){Stringvalue=posStack.pop();如果(值==null){返回null;}Nodehead=newNode(Integer.parseInt(value));head.right=posB(posStack);head.left=posB(posStack);返回头部;}2。为什么没有顺序序列化?二叉树不能通过中序遍历进行序列化和反序列化,因为两棵不同的树可能得到相同的中序序列。这个时候无法确定这个中序序列代表的是哪棵二叉树。序列化与反序列化1.序列化(1)准备一个队列放结果(节点的字符串值),准备一个辅助队列(存放节点)(2)将头节点的值放入结果队列,把头节点进入辅助队列(3)弹出辅助队列的头节点,1)该节点的左孩子不为空,将左孩子节点的值放入结果队列,将左孩子放入结果队列辅助队列;如果节点左子节点为空,则在结果队列中放入空值,辅助队列保持不变。2)如果该节点的右孩子不为空,则将右孩子节点的值放入结果队列,将右孩子放入辅助队列;如果该节点的右孩子为空,则将空值放入结果队列,辅助队列保持不变。(4)一直执行第3步,直到辅助队列为空。/***按层序列化**@authorJava和算法学习:周一*/publicstaticQueuelevelSerial(Nodehead){Queueans=newLinkedList<>();如果(head==null){ans.offer(null);}else{//将头节点的值放入结果队列ans.add(String.valueOf(head.value));//准备一个辅助队列Queuehelp=newLinkedList<>();//将辅助队列放入头节点help.offer(head);while(!help.isEmpty()){Nodecurrent=help.poll();//辅助队列头节点的左子节点不为空if(current.left!=null){//将左子节点的值放入结果队列ans.offer(String.valueOf(current.left.value));//将左孩子放入辅助队列Offer(Current.left);}else{//将NULL放入结果队列,辅助队列不变Ans.offer(null);}//右孩子同原因如果(Current.richt!=NULL){Ans.offer(String.valueOf(current.right.value));help.offer(当前t.对);}}else{ans.offer(null);}}}}returnans;}2.反序列化(1)从原队列中pop第一个值,反序列化生成一个头节点(2)准备一个Auxiliary队列(放置节点),放入头节点(3)弹出辅助队列的第一个节点current,从原队列中弹出一个值,反序列化为current的左孩子;然后从原队列中弹出一个值,反序列化为current的右孩子(4)如果current的左孩子不为空,则放入辅助队列;如果current的右孩子不为空,则放入辅助队列(5)重复步骤3和4,直到辅助队列为空/***逐层反序列化**@authorJava与算法学习:周一*/publicstaticNodebuildByLevel(Queuequeue){if(queue==null||queue.size()==0){returnnull;}//反序列化并构建头节点Nodehead=generateNode(queue.poll());//准备一个辅助队列Queuehelp=newLinkedList<>();//防止队列中只有一个null。如果队列中只有一个null,则整个方法直接结束if(head!=null){//将辅助队列放入头节点help.offer(head);}节点电流;while(!help.isEmpty()){//弹出辅助队列的第一个节点current=help.poll();//反序列化并构建左子节点current.left=generateNode(queue.poll());//反序列化并构建右子节点current.right=generateNode(queue。轮询());if(current.left!=null){//左孩子不为空,将左孩子放入辅助队列help.offer(current.left);}if(current.right!=null){//右孩子不为空,将右孩子放入辅助队列help.offer(current.right);}}returnhead;}??本文所有代码地址:https://github.com/monday-pro/algorithm-study/blob/master/src/basic/binarytree/SerializeAndDeserializeTree.java