简单来说,二叉树的序列化就是将二叉树用一个字符串来表示,反序列化就是将字符串还原回树结构。
1. 先序序列化及其反序列化:在先序遍历过程中,若当前节点非空,则将其数值加入字符串(value值加一条下划线,用来分离不同数值),若当前节点为空节点,则在字符串中加入“#_”。
2.中序以及后序序列化及其反序列化同先序方法。
3. 按层序列化及其反序列化:【顾名思义,就是一层一层来序列化二叉树】
序列化过程:设置一个队列,先将头节点加入队列。开始遍历,遍历过程中先弹出队列头元素,若当前节点非空,则将该节点的左右孩子加入队列,并将该节点数值加入字符串,若当前节点为空节点,则直接在字符串中加入“#_”。
反序列化过程:设置一个队列,头节点直接设置为字符串的第一个元素(非空),并将该节点加入队列。开始遍历,队列非空,则遍历过程中先弹出队列头元素,若该节点不是空节点,则设置左孩子和有孩子的数值为字符串依次顺序弹出的值,若左右孩子不是空节点,则将左孩子和右孩子加入到队列中。直至队列为空。
package algorithm.section5;
import java.util.LinkedList;
import java.util.Queue;
import java.util.Stack;
public class SerializeAndReconstructTree {
public static class Node{
public int value;
public Node left;
public Node right;
public Node(int value){
this.value = value;
}
}
public static String serializePreOrder(Node head){
if (head == null) return "#_";
String res = head.value + "_";
res += serializePreOrder(head.left);
res += serializePreOrder(head.right);
return res;
}
public static Node preOrderReconstructPrepare(String res){
if (res.isEmpty()) return null;
String[] flag = res.split("_");
Queue<String> f = new LinkedList<>();
for (String s : flag) f.offer(s);
return reconstructPreOrder(f);
}
public static Node reconstructPreOrder(Queue<String> f){
if (f.isEmpty()) return null;
String flag = f.poll();
if (flag.equals("#")) return null;
Node node = new Node(Integer.parseInt(flag));
node.left = reconstructPreOrder(f);
node.right = reconstructPreOrder(f);
return node;
}
public static String serializeInOrder(Node head){
if (head == null) return "#_";
String res = "";
res += serializeInOrder(head.left);
res += head.value + "_";
res += serializeInOrder(head.right);
return res;
}
public static Node inOrderReconstructPrepare(String res){
if (res.isEmpty()) return null;
String[] flag = res.split("_");
Queue<String> f = new LinkedList<>();
for (String s : flag) f.offer(s);
return reconstructInOrder(f);
}
public static Node reconstructInOrder(Queue<String> f){
if (f.isEmpty()) return null;
String flag = f.poll();
if (flag.equals("#")) return null;
Node node = null;
node.left = reconstructInOrder(f);
node = new Node(Integer.parseInt(flag));
node.right = reconstructInOrder(f);
return node;
}
public static String serializePosOrder(Node head){
if (head == null) return "#_";
String res = "";
res += serializePosOrder(head.left);
res += serializePosOrder(head.right);
res += head.value + "_";
return res;
}
public static Node posOrderReconstructPrepare(String res){
if (res.isEmpty()) return null;
String[] flag = res.split("_");
Queue<String> f = new LinkedList<>();
for (String s : flag) f.offer(s);
return reconstructPosOrder(f);
}
public static Node reconstructPosOrder(Queue<String> f){
if (f.isEmpty()) return null;
String flag = f.poll();
if (flag.equals("#")) return null;
Node node = null;
node.left = reconstructPosOrder(f);
node.right = reconstructPosOrder(f);
node = new Node(Integer.parseInt(flag));
return node;
}
public static String serialByLevel(Node head){
if (head == null) return "#_";
Queue<Node> queue = new LinkedList<>();
queue.offer(head);
String res = "";
while (!queue.isEmpty()){
Node flag = queue.poll();
if (flag == null) res += "#_";
else {
res = res + flag.value + "_";
queue.offer(flag.left);
queue.offer(flag.right);
}
}
return res;
}
public static Node reconByLevelString(String res){
if (res.isEmpty()) return null;
String[] flag = res.split("_");
if (flag[0].equals("#")) return null;
Queue<Node> queue = new LinkedList<>();
int index = 1;
Node head = produceNode(flag[0]);
queue.offer(head);
while (!queue.isEmpty()){
Node node = queue.poll();
node.left = produceNode(flag[index++]);
node.right = produceNode(flag[index++]);
if (node.left != null) queue.offer(node.left);
if (node.right != null) queue.offer(node.right);
}
return head;
}
public static Node produceNode(String s){
if (s.equals("#")) return null;
else return new Node(Integer.parseInt(s));
}
// for test -- print tree
public static void printTree(Node head) {
System.out.println("Binary Tree:");
printInOrder(head, 0, "H", 17);
System.out.println();
}
public static void printInOrder(Node head, int height, String to, int len) {
if (head == null) {
return;
}
printInOrder(head.right, height + 1, "v", len);
String val = to + head.value + to;
int lenM = val.length();
int lenL = (len - lenM) / 2;
int lenR = len - lenM - lenL;
val = getSpace(lenL) + val + getSpace(lenR);
System.out.println(getSpace(height * len) + val);
printInOrder(head.left, height + 1, "^", len);
}
public static String getSpace(int num) {
String space = " ";
StringBuffer buf = new StringBuffer("");
for (int i = 0; i < num; i++) {
buf.append(space);
}
return buf.toString();
}
public static void main(String[] args) {
Node head = null;
printTree(head);
String pre = serializePreOrder(head);
System.out.println("serialize tree by pre-order: " + pre);
head = preOrderReconstructPrepare(pre);
System.out.print("reconstruct tree by pre-order, ");
printTree(head);
String level = serialByLevel(head);
System.out.println("serialize tree by level: " + level);
head = reconByLevelString(level);
System.out.print("reconstruct tree by level, ");
printTree(head);
System.out.println("====================================");
head = new Node(1);
printTree(head);
pre = serializePreOrder(head);
System.out.println("serialize tree by pre-order: " + pre);
head = preOrderReconstructPrepare(pre);
System.out.print("reconstruct tree by pre-order, ");
printTree(head);
level = serialByLevel(head);
System.out.println("serialize tree by level: " + level);
head = reconByLevelString(level);
System.out.print("reconstruct tree by level, ");
printTree(head);
System.out.println("====================================");
head = new Node(1);
head.left = new Node(2);
head.right = new Node(3);
head.left.left = new Node(4);
head.right.right = new Node(5);
printTree(head);
pre = serializePreOrder(head);
System.out.println("serialize tree by pre-order: " + pre);
head = preOrderReconstructPrepare(pre);
System.out.print("reconstruct tree by pre-order, ");
printTree(head);
level = serialByLevel(head);
System.out.println("serialize tree by level: " + level);
head = reconByLevelString(level);
System.out.print("reconstruct tree by level, ");
printTree(head);
System.out.println("====================================");
head = new Node(100);
head.left = new Node(21);
head.left.left = new Node(37);
head.right = new Node(-42);
head.right.left = new Node(0);
head.right.right = new Node(666);
printTree(head);
pre = serializePreOrder(head);
System.out.println("serialize tree by pre-order: " + pre);
head = preOrderReconstructPrepare(pre);
System.out.print("reconstruct tree by pre-order, ");
printTree(head);
level = serialByLevel(head);
System.out.println("serialize tree by level: " + level);
head = reconByLevelString(level);
System.out.print("reconstruct tree by level, ");
printTree(head);
System.out.println("====================================");
}
}