便於存儲將二叉樹等數據結構轉化爲字符串的形式的磁盤中存儲,使用的時候再由字符串轉換爲二叉樹結構即可。下文以先序遍歷爲例實現二叉樹的序列化及反序列化。
此外由於結點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;
}