携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第18天,二叉树的序列化与反序列化[前序遍历+回溯] - 掘金 (juejin.cn)
前言
对于树的序列化和反序列化,用什么遍历序列化,就用什么遍历把其还原出来,本文记录前序遍历序列化,采用回溯+模拟树左右递归来生成树。
一、二叉树的序列化与反序列化
二、前序遍历 & 回溯生成树
package everyday.hard;
public class Codec {
// 先遍历形成字符串,再遍历字符串回溯生成树。
// Encodes a tree to a single string.
public String serialize(TreeNode root) {
preOrder(root);
return sb.deleteCharAt(sb.length() - 1).toString();
}
StringBuilder sb = new StringBuilder();
private void preOrder(TreeNode root) {
if (root == null) {
sb.append("#,");
return;
}
int len = sb.length();
sb.append(root.val).append(',');
preOrder(root.left);
preOrder(root.right);
}
// Decodes your encoded data to tree.
public TreeNode deserialize(String data) {
String[] strs = data.split(",");
return buildTree(strs);
}
private TreeNode buildTree(String[] strs) {
if (idx == strs.length) return null;
if ("#".equals(strs[idx])) {
++idx;
return null;
}
// bug1:有负数的情况就乱了!
TreeNode root = new TreeNode(Integer.parseInt(strs[idx++]));
// 模拟左右孩子递归。
root.left = buildTree(strs);
root.right = buildTree(strs);
return root;
}
int idx;
// Definition for a binary tree node.
public class TreeNode {
int val;
TreeNode left;
TreeNode right;
TreeNode(int x) {
val = x;
}
}
}
总结
1)树的遍历 & 如何生成树,本质都是从子树构建处更大的子树,前序遍历如果有null的记录,则不断遍历值的来回溯生成;另一种就是典型的中序遍历 + 前序/后序,主要就算不断的分区间,直到一个区间只有一个节点 || 没有节点,分别表示叶子节点和空节点。
2)树问题,可归类为前序遍历 & dfs,中序遍历 & 平衡二叉,后序遍历 & 回溯,层序遍历 & bfs.