便于存储将二叉树等数据结构转化为字符串的形式的磁盘中存储,使用的时候再由字符串转换为二叉树结构即可。下文以先序遍历为例实现二叉树的序列化及反序列化。
此外由于结点val的长度未知,避免歧义,在序列化的过程中在每一个节点结束位置都插入 !字符;对于空元素也应使用一特殊字符‘#’标记。
序列化过程使用的就是二叉树的先序遍历,不过遍历过程中需将空值也存储起来。实现代码如下:
public static String serialization(TreeNode root) {
StringBuilder sb = new StringBuilder();
preOrder(root, sb);
return sb.toString();
}
public static void preOrder(TreeNode root, StringBuilder sb) {
if (root == null) {
sb.append("#!");
return;
}
sb.append(root.val);
sb.append('!');
preOrder(root.left, sb);
preOrder(root.right, sb);
}
反序列化过程实现思路如下:
首先利用分隔符‘!’将字符串切割成字符串数组strs。
并且利用字符串数组第一个元素创建头结点root(若其不为‘#’时),创建一堆栈,将刚创建的头结点入栈。字符串数组从下标一开始遍历。
当堆栈不为空时:
遍历字符串数组,直到出现‘#’为止,遍历过程中利用strs当前元素创建子结点作为栈顶元素的左孩子,并且入栈;
然后弹出栈顶元素,判断下一位置的字符串是否为‘#’,若不为空,该元素构成的结点作为之前弹出的栈顶元素的右孩子,并把该节点入栈。
不断重复上述过程。
实现代码如下:
public static TreeNode deSerialize(String serial) {
String[] strs = serial.split("!");
TreeNode root = new TreeNode(Integer.parseInt(strs[0]));
Stack<TreeNode> stack = new Stack<>();
stack.push(root);
int index = 1;
while (!stack.isEmpty()) {
while(!"#".equals(strs[index])) {
stack.peek().left = new TreeNode(Integer.parseInt(strs[index++]));
stack.push(stack.peek().left);
}
index++;
TreeNode current = stack.pop();
if(!"#".equals(strs[index])) {
current.right = new TreeNode(Integer.parseInt(strs[index++]));
stack.push(current.right);
}
}
return root;
}