二叉树——序列化、反序列化

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;
}
posted @   迈吉  阅读(34)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 终于写完轮子一部分:tcp代理 了,记录一下
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
点击右上角即可分享
微信分享提示