二叉树——序列化、反序列化
1. 二叉树的序列化、反序列化
1.1. 问题
将一个二叉树序列化为字符串。
从序列化后的字符串重建一棵二叉树。
1.2. 思路
用#
表示空节点,用!
表示一个节点的结尾。
这道题可以用二叉树的前序遍历、后序遍历、层序遍历来做。
中序遍历不好做,因为给定一个序列后,没办法一下子将根节点找出来。
对于前序、后序遍历,可以考虑递归和使用栈的方法来弄,使用morris遍历不好做。因为序列化后的字符串需要包含空节点的信息,而morris遍历,不好来拿空节点的信息。
1.3. 代码
1.3.1. 前序法
public static String serializeByPre(TreeNode<Integer> root) {
StringBuilder builder = new StringBuilder();
buildPreStr(root, builder);
return builder.toString();
}
private static void buildPreStr(TreeNode<Integer> 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<Integer> deserializeByPre(String str) {
String[] strs = str.split("!");
Queue<String> queue = new LinkedList<>(Arrays.asList(strs));
return buildTreeByPre(queue);
}
private static TreeNode<Integer> buildTreeByPre(Queue<String> queue) {
String str = queue.remove();
if ("#".equals(str)) {
return null;
}
TreeNode<Integer> node = new TreeNode<>(Integer.valueOf(str));
node.left = buildTreeByPre(queue);
node.right = buildTreeByPre(queue);
return node;
}
1.3.2. 后序法
public static String serializeByPost(TreeNode<Integer> root) {
if (root == null) {
return "#!";
}
StringBuilder builder = new StringBuilder();
buildPostStr(root, builder);
return builder.toString();
}
private static void buildPostStr(TreeNode<Integer> 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<Integer> deserializeByPost(String postStr) {
String[] nodes = postStr.split("!");
Stack<String> stack = new Stack<>();
for (String s :nodes) {
stack.push(s);
}
return buildTreeByPost(stack);
}
public static TreeNode<Integer> buildTreeByPost(Stack<String> stack) {
String s = stack.pop();
if(s.equals("#")) {
return null;
}
TreeNode<Integer> head = new TreeNode<>(Integer.valueOf(s));
head.right = buildTreeByPost(stack);
head.left = buildTreeByPost(stack);
return head;
}
1.3.3. 层序法
public static String serializeByLevel(TreeNode<Integer> root) {
if (root == null) {
return "#!";
}
StringBuilder builder = new StringBuilder();
Queue<TreeNode<Integer>> queue = new LinkedList<>();
queue.add(root);
TreeNode<Integer> nil = new TreeNode<>();
while (!queue.isEmpty()) {
TreeNode<Integer> 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<Integer> deserializeByLevel(String data) {
if (data == null || data.isEmpty() || "#!".equals(data)) {
return null;
}
Queue<String> children = new LinkedList<>(Arrays.asList(data.split("!")));
Queue<TreeNode<Integer>> parents = new LinkedList<>();
TreeNode<Integer> root = new TreeNode<>(Integer.valueOf(children.remove()))
parents.add(root);
while (!parents.isEmpty()) {
TreeNode<Integer> node = parents.remove();
String leftVal = children.remove();
String rightVal = children.remove();
if ("#".equals(leftVal)) {
node.left = null;
} else {
TreeNode<Integer> left = new TreeNode<>(Integer.valueOf(leftVal));
node.left = left;
parents.add(left);
}
if ("#".equals(rightVal)) {
node.right = null;
} else {
TreeNode<Integer> right = new TreeNode<>(Integer.valueOf(rightVal));
node.right = right;
parents.add(right);
}
}
return root;
}
作者: 迈吉
出处: https://www.cnblogs.com/stepfortune/
关于作者:迈吉
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出, 原文链接 如有问题, 可邮件(showable@qq.com)咨询.