题目描述
请实现两个函数,分别用来序列化和反序列化二叉树
思路:
序列化是指把树变成一个String,反序列化是指从String重建树,并返回树的root。
之前已经得出可以通过前序和中序遍历确定一个二叉树。
反序列化是运用了之前的思路。(重建二叉树那道题)
public class Solution {
StringBuilder result = new StringBuilder();
String Serialize(TreeNode root) {
TreeNode temp = root;
preSort(temp);
inSort(root);
return result.toString();
}
TreeNode Deserialize(String str) {
String[] origin = str.split("#");
int length = origin.length/2;
int[] pre = new int[length];
int[] in = new int[length];
for(int i = 0; i<length; i++){
pre[i] = Integer.valueOf(origin[i]);
in[i] = Integer.valueOf(origin[i+length]);
}
TreeNode root = reConstructBinaryTree(pre, 0, pre.length - 1, in, 0, in.length - 1);
return root;
}
private TreeNode reConstructBinaryTree(int[] pre, int startPre, int endPre, int[] in, int startIn, int endIn) {
if (startPre > endPre || startIn > endIn)
return null;
TreeNode root = new TreeNode(pre[startPre]);
for (int i = startIn; i <= endIn; i++)
if (in[i] == pre[startPre]) {
root.left = reConstructBinaryTree(pre, startPre + 1, startPre + i - startIn, in, startIn, i - 1);
root.right = reConstructBinaryTree(pre, i - startIn + startPre + 1, endPre, in, i + 1, endIn);
}
return root;
}
void preSort(TreeNode root){
if(root==null)
return;
result.append(root.val);
result.append("#");
preSort(root.left);
preSort(root.right);
}
void inSort(TreeNode root){
if(root==null)
return;
inSort(root.left);
result.append(root.val);
result.append("#");
inSort(root.right);
}
}
之前这个面试题6的思路是有条件限制的,一是不能有重复的节点(否则遍历找节点的时候就会出错了),二是只有当两个序列中所有数据都读出后才能开始反序列化。如果两个遍历序列的数据是从一个流里读出来的,那就可能需要等较长的时间。
剑指offer思路:
因为把空节点设为“#”,所以仅通过前序遍历即可反序列化,并且有相同数值的节点也不会干扰
public class Solution {
public int index = -1;
String Serialize(TreeNode root) {
StringBuffer sb = new StringBuffer();
if(root == null){
sb.append("#,");
return sb.toString();
}
sb.append(root.val + ",");
sb.append(Serialize(root.left));
sb.append(Serialize(root.right));
return sb.toString();
}
TreeNode Deserialize(String str) {
index++;
int len = str.length();
if(index >= len){
return null;
}
String[] strr = str.split(",");
TreeNode node = null;
if(!strr[index].equals("#")){ // 因为是前序遍历的场景,所以当某个位置上的点是#时,意味着该点为null,且不存在左右结点,所以直接返回
node = new TreeNode(Integer.valueOf(strr[index]));
node.left = Deserialize(str);
node.right = Deserialize(str);
}
return node;
}
}
static StringBuilder sb = null;
static String Serialize(TreeNode root) {
if (root == null)
return "#";
sb = new StringBuilder();
Serialize_solve(root);
String s = sb.toString();
return s.substring(0, s.length() - 1);
}
private static void Serialize_solve(TreeNode root) {
if (root == null) {
sb.append("#,");
return;
}
sb.append(root.val + ",");
Serialize_solve(root.left);
Serialize_solve(root.right);
}
static int index;
static TreeNode Deserialize(String str) {
if (str == null || str.trim().equals(""))
return null;
String[] strs = str.split(",");
index = 0;
return Deserialize_solve(strs);
}
private static TreeNode Deserialize_solve(String[] chars) {
if (chars[index].equals("#")) {
index++;
return null;
}
System.out.println(chars[index]);
TreeNode node = new TreeNode(Integer.parseInt(chars[index++]));
node.left = Deserialize_solve(chars);
node.right = Deserialize_solve(chars);
return node;
}
}