|
|
|
@ -2,9 +2,25 @@ package class07;
|
|
|
|
|
|
|
|
|
|
import java.util.LinkedList;
|
|
|
|
|
import java.util.Queue;
|
|
|
|
|
import java.util.Stack;
|
|
|
|
|
|
|
|
|
|
public class Code04_SerializeAndReconstructTree {
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* 二叉树可以通过先序、后序或者按层遍历的方式序列化和反序列化,
|
|
|
|
|
* 以下代码全部实现了。
|
|
|
|
|
* 但是,二叉树无法通过中序遍历的方式实现序列化和反序列化
|
|
|
|
|
* 因为不同的两棵树,可能得到同样的中序序列,即便补了空位置也可能一样。
|
|
|
|
|
* 比如如下两棵树
|
|
|
|
|
* __2
|
|
|
|
|
* /
|
|
|
|
|
* 1
|
|
|
|
|
* 和
|
|
|
|
|
* 1__
|
|
|
|
|
* \
|
|
|
|
|
* 2
|
|
|
|
|
* 补足空位置的中序遍历结果都是{ null, 1, null, 2, null}
|
|
|
|
|
*
|
|
|
|
|
* */
|
|
|
|
|
public static class Node {
|
|
|
|
|
public int value;
|
|
|
|
|
public Node left;
|
|
|
|
@ -31,6 +47,38 @@ public class Code04_SerializeAndReconstructTree {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static Queue<String> inSerial(Node head) {
|
|
|
|
|
Queue<String> ans = new LinkedList<>();
|
|
|
|
|
ins(head, ans);
|
|
|
|
|
return ans;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static void ins(Node head, Queue<String> ans) {
|
|
|
|
|
if (head == null) {
|
|
|
|
|
ans.add(null);
|
|
|
|
|
} else {
|
|
|
|
|
ins(head.left, ans);
|
|
|
|
|
ans.add(String.valueOf(head.value));
|
|
|
|
|
ins(head.right, ans);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static Queue<String> posSerial(Node head) {
|
|
|
|
|
Queue<String> ans = new LinkedList<>();
|
|
|
|
|
poss(head, ans);
|
|
|
|
|
return ans;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static void poss(Node head, Queue<String> ans) {
|
|
|
|
|
if (head == null) {
|
|
|
|
|
ans.add(null);
|
|
|
|
|
} else {
|
|
|
|
|
poss(head.left, ans);
|
|
|
|
|
poss(head.right, ans);
|
|
|
|
|
ans.add(String.valueOf(head.value));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static Node buildByPreQueue(Queue<String> prelist) {
|
|
|
|
|
if (prelist == null || prelist.size() == 0) {
|
|
|
|
|
return null;
|
|
|
|
@ -49,6 +97,28 @@ public class Code04_SerializeAndReconstructTree {
|
|
|
|
|
return head;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static Node buildByPosQueue(Queue<String> poslist) {
|
|
|
|
|
if (poslist == null || poslist.size() == 0) {
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
Stack<String> stack = new Stack<>();
|
|
|
|
|
while (!poslist.isEmpty()) {
|
|
|
|
|
stack.push(poslist.poll());
|
|
|
|
|
}
|
|
|
|
|
return posb(stack);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static Node posb(Stack<String> posstack) {
|
|
|
|
|
String value = posstack.pop();
|
|
|
|
|
if (value == null) {
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
Node head = new Node(Integer.valueOf(value));
|
|
|
|
|
head.right = posb(posstack);
|
|
|
|
|
head.left = posb(posstack);
|
|
|
|
|
return head;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static Queue<String> levelSerial(Node head) {
|
|
|
|
|
Queue<String> ans = new LinkedList<>();
|
|
|
|
|
if (head == null) {
|
|
|
|
@ -140,20 +210,54 @@ public class Code04_SerializeAndReconstructTree {
|
|
|
|
|
return isSameValueStructure(head1.left, head2.left) && isSameValueStructure(head1.right, head2.right);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// for test
|
|
|
|
|
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) {
|
|
|
|
|
int maxLevel = 5;
|
|
|
|
|
int maxValue = 100;
|
|
|
|
|
int testTimes = 1000000;
|
|
|
|
|
System.out.println("test begin");
|
|
|
|
|
for (int i = 0; i < testTimes; i++) {
|
|
|
|
|
Node head = generateRandomBST(maxLevel, maxValue);
|
|
|
|
|
Queue<String> pre = preSerial(head);
|
|
|
|
|
Queue<String> pos = posSerial(head);
|
|
|
|
|
Queue<String> level = levelSerial(head);
|
|
|
|
|
Node preBuild = buildByPreQueue(pre);
|
|
|
|
|
Node posBuild = buildByPosQueue(pos);
|
|
|
|
|
Node levelBuild = buildByLevelQueue(level);
|
|
|
|
|
if (!isSameValueStructure(preBuild, levelBuild)) {
|
|
|
|
|
if (!isSameValueStructure(preBuild, posBuild) || !isSameValueStructure(posBuild, levelBuild)) {
|
|
|
|
|
System.out.println("Oops!");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
System.out.println("finish!");
|
|
|
|
|
System.out.println("test finish!");
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|