1、题目描述
【JZ61】请实现两个函数,分别用来序列化和反序列化二叉树。
二叉树的序列化是指:把一棵二叉树按照某种遍历方式的结果以某种格式保存为字符串,从而使得内存中建立起来的二叉树可以持久保存。序列化可以基于先序、中序、后序、层序的二叉树遍历方式来进行修改,序列化的结果是一个字符串,序列化时通过某种符号表示空节点(#),以 ! 表示一个结点值的结束(value!)。
二叉树的反序列化是指:根据某种遍历顺序得到的序列化字符串结果str,重构二叉树。
例如,我们可以把一个只有根节点为1的二叉树序列化为"1!",然后通过自己的函数来解析回这个二叉树。
知识点:二叉树,先序遍历,层次遍历
难度:☆☆
2、解题思路
前序遍历序列化算法步骤:
1、定义一个 StringBuilder 类型对象 sb;
2、从根结点开始:
2.1 如果结点为空,则执行sb.append("#!")
并return
;
2.2 如果结点不为空,则sb.append(root.val + "!");
;
2.3 对左子结点回到 2.1 执行;
2.4 对右子结点回到 2.1 执行。
反序列化算法步骤:
1、定义一个 int 类型变量 index 用来当前正在反序列化第几个结点,初始值为 -1;
2、每反序列化一个结点之前先执行index++
;
3、把 str 字符串以 '!'
为分隔符,变为 String[] 类型的 strs;
4、开始遍历 strs
,每遍历一个 str[index]
之前,先 index++
,说明当前遍历第 index
个:
4.1 如果 str[index] == '#'
,则直接return
;
4.2 如果 str[index] != '#'
,则:
4.2.1 TreeNode root = new TreeNode(0);
4.2.2 root.val = Integer.parseInt(strs[index]);
5、对 root 的左结点回到 4.1 ;
6、对 root 的右结点回到 4.2。
3、解题代码
package pers.klb.jzoffer.hard;
import pers.klb.jzoffer.simple.TreeNode;
/**
* @program: JzOffer2021
* @description: 序列化二叉树
* @author: Meumax
* @create: 2020-07-19 10:42
**/
public class SerializeTree {
String Serialize(TreeNode root) {
if(root == null)
return "";
StringBuilder sb = new StringBuilder();
doSerialize(root, sb);
return sb.toString();
}
void doSerialize(TreeNode root, StringBuilder sb) {
if(root == null) {
sb.append("#!");
return;
}
sb.append(root.val);
sb.append('!');
doSerialize(root.left, sb);
doSerialize(root.right, sb);
}
int index = -1;
TreeNode Deserialize(String str) {
if(str.length() == 0)
return null;
String[] strs = str.split("!");
return doDeserialize(strs);
}
TreeNode doDeserialize(String[] strs) {
index++;
if(!strs[index].equals("#")) {
TreeNode root = new TreeNode(0);
root.val = Integer.parseInt(strs[index]);
root.left = doDeserialize(strs);
root.right = doDeserialize(strs);
return root;
}
return null;
}
}
4、解题心得
本题难度适中,主要考察树的遍历。