二叉树——序列化、反序列化
1. 二叉树的序列化、反序列化
1.1. 问题
将一个二叉树序列化为字符串。
从序列化后的字符串重建一棵二叉树。
1.2. 思路
用#表示空节点,用!表示一个节点的结尾。
这道题可以用二叉树的前序遍历、后序遍历、层序遍历来做。
中序遍历不好做,因为给定一个序列后,没办法一下子将根节点找出来。
对于前序、后序遍历,可以考虑递归和使用栈的方法来弄,使用morris遍历不好做。因为序列化后的字符串需要包含空节点的信息,而morris遍历,不好来拿空节点的信息。
1.3. 代码
1.3.1. 前序法
public static String serializeByPre(TreeNode root) {
StringBuilder builder = new StringBuilder();
buildPreStr(root, builder);
return builder.toString();
}
private static void buildPreStr(TreeNode node, StringBuilder builder) {
if (node == null) {
builder.append("#!");
return;
}
builder.append(node.val).append("!");
buildPreStr(node.left, builder);
buildPreStr(node.right, builder);
}
public static TreeNode deserializeByPre(String str) {
String[] strs = str.split("!");
Queue queue = new LinkedList<>(Arrays.asList(strs));
return buildTreeByPre(queue);
}
private static TreeNode buildTreeByPre(Queue queue) {
String str = queue.remove();
if ("#".equals(str)) {
return null;
}
TreeNode node = new TreeNode<>(Integer.valueOf(str));
node.left = buildTreeByPre(queue);
node.right = buildTreeByPre(queue);
return node;
}
1.3.2. 后序法
public static String serializeByPost(TreeNode root) {
if (root == null) {
return "#!";
}
StringBuilder builder = new StringBuilder();
buildPostStr(root, builder);
return builder.toString();
}
private static void buildPostStr(TreeNode head, StringBuilder builder) {
if (head == null) {
builder.append("#!");
return;
}
buildPostStr(head.left, builder);
buildPostStr(head.right, builder);
builder.append(head.val);
builder.append('!');
}
public static TreeNode deserializeByPost(String postStr) {
String[] nodes = postStr.split("!");
Stack stack = new Stack<>();
for (String s :nodes) {
stack.push(s);
}
return buildTreeByPost(stack);
}
public static TreeNode buildTreeByPost(Stack stack) {
String s = stack.pop();
if(s.equals("#")) {
return null;
}
TreeNode head = new TreeNode<>(Integer.valueOf(s));
head.right = buildTreeByPost(stack);
head.left = buildTreeByPost(stack);
return head;
}
1.3.3. 层序法
public static String serializeByLevel(TreeNode root) {
if (root == null) {
return "#!";
}
StringBuilder builder = new StringBuilder();
Queue> queue = new LinkedList<>();
queue.add(root);
TreeNode nil = new TreeNode<>();
while (!queue.isEmpty()) {
TreeNode node = queue.remove();
if (node == nil) {
builder.append("#");
} else {
builder.append(node.val);
queue.add(node.left == null ? nil : node.left);
queue.add(node.right == null ? nil : node.right);
}
builder.append("!");
}
return builder.toString();
}
public static TreeNode deserializeByLevel(String data) {
if (data == null || data.isEmpty() || "#!".equals(data)) {
return null;
}
Queue children = new LinkedList<>(Arrays.asList(data.split("!")));
Queue> parents = new LinkedList<>();
TreeNode root = new TreeNode<>(Integer.valueOf(children.remove()))
parents.add(root);
while (!parents.isEmpty()) {
TreeNode node = parents.remove();
String leftVal = children.remove();
String rightVal = children.remove();
if ("#".equals(leftVal)) {
node.left = null;
} else {
TreeNode left = new TreeNode<>(Integer.valueOf(leftVal));
node.left = left;
parents.add(left);
}
if ("#".equals(rightVal)) {
node.right = null;
} else {
TreeNode right = new TreeNode<>(Integer.valueOf(rightVal));
node.right = right;
parents.add(right);
}
}
return root;
}