算法 - 序列化二叉树
题目
请实现两个函数,分别用来序列化和反序列化二叉树
二叉树的序列化是指:把一棵二叉树按照某种遍历方式的结果以某种格式保存为字符串,从而使得内存中建立起来的二叉树可以持久保存。序列化可以基于先序、中序、后序、层序的二叉树遍历方式来进行修改,序列化的结果是一个字符串,序列化时通过 某种符号表示空节点(#),以 ! 表示一个结点值的结束(value!)。
二叉树的反序列化是指:根据某种遍历顺序得到的序列化字符串结果str,重构二叉树。
例如,我们可以把一个只有根节点为1的二叉树序列化为"1,",然后通过自己的函数来解析回这个二叉树
思考
这道题考验的是二叉树的遍历!参考了别人的解法,有使用层次遍历解法也有前序遍历解法。
但是我了下逻辑都挺麻烦,便想找个相对逻辑简单的解法。
我想到了 “二叉堆”,二叉堆是二叉树的数组形式。
序列化 -> 思路就是将二叉树通过 堆 这一个中介 转换为字符串。
反序列化 -> 将字符串转换为堆,然后将堆转换为二叉树。
虽然看似中间多了一层转换,感觉麻烦了些,但是看下代码就知道,其实是比其他解法简单了。因为我这里也算是将复杂问题进行拆解,别人都是一步到位,但是这一步太麻烦,而我是分两步走,然而两步都非常简单,你选哪个?
上码
// 序列化
static String Serialize(TreeNode root) {
Object[] array = new Object[50];
serRecursive(array, 1, root);
StringBuilder builder = new StringBuilder();
for (Object s : array) {
if (s == null) {
builder.append("#").append(",");
} else {
builder.append(s).append(",");
}
}
return builder.toString();
}
// 递归将二叉树对应到数组堆
private static void serRecursive(Object[] array, Integer nodeIdx, TreeNode node) {
if (node == null) {
return;
}
array[nodeIdx - 1] = node.val;
serRecursive(array, nodeIdx * 2, node.left);
serRecursive(array, nodeIdx * 2 + 1, node.right);
}
// 反序列化
static TreeNode Deserialize(String str) {
List<String> list = Arrays.asList(str.split(","));
String r0 = list.get(0);
if ("#".equals(r0)) {
return null;
}
TreeNode root = new TreeNode(Integer.parseInt(r0));
desRecursive(list, 1, root);
return root;
}
// 递归将数组堆还原成二叉树
private static void desRecursive(List<String> list, Integer nodeIdx, TreeNode node) {
int l = nodeIdx * 2;
int r = nodeIdx * 2 + 1;
int size = list.size();
if ((l - 1) < size && !"#".equals(list.get(l - 1))) {
TreeNode lnode = new TreeNode(Integer.parseInt(list.get(l - 1)));
node.left = lnode;
desRecursive(list, l, lnode);
}
if ((r - 1) < size && !"#".equals(list.get(r - 1))) {
TreeNode lnode = new TreeNode(Integer.parseInt(list.get(r - 1)));
node.right = lnode;
desRecursive(list, r, lnode);
}
}