【劍指offer較難部分22】序列化二叉樹(java)
阿新 • • 發佈:2021-02-04
題目描述
請實現兩個函式,分別用來序列化和反序列化二叉樹
二叉樹的序列化是指:把一棵二叉樹按照某種遍歷方式的結果以某種格式儲存為字串,從而使得記憶體中建立起來的二叉樹可以持久儲存。序列化可以基於先序、中序、後序、層序的二叉樹遍歷方式來進行修改,序列化的結果是一個字串,序列化時通過 某種符號表示空節點(#),以 ! 表示一個結點值的結束(value!)。
二叉樹的反序列化是指:根據某種遍歷順序得到的序列化字串結果str,重構二叉樹。
例如,我們可以把一個只有根節點為1的二叉樹序列化為"1,",然後通過自己的函式來解析回這個二叉樹
分析
這就相當於先遍歷二叉樹,轉成字串,然後再由字串轉化回原來二叉樹
二叉樹可以用遞迴與非遞迴
1、遞迴
public class Solution {
/**
*序列化:變成字串
*/
String Serialize(TreeNode root) {
if (root == null) {
return "";
}
StringBuffer sb = new StringBuffer();
serializeHelper(root, sb);
if (sb.length() != 0)
sb.deleteCharAt(sb.length()-1);//處理最後一個逗號
return sb.toString();
}
void serializeHelper(TreeNode node, StringBuffer sb) {
if (node == null) {
sb.append("#,");
return;
}
// 處理非null元素
sb.append (node.val + ",");
// 處理左右孩子節點
serializeHelper(node.left, sb);
serializeHelper(node.right, sb);
}
/**
* 反序列化,解析字串為二叉樹
*/
TreeNode Deserialize(String str) {
if (str == null || str.length() == 0) {
return null;
}
String[] strArr = str.split(",");
return deserializeHelper(strArr);
}
private int index = -1;
TreeNode deserializeHelper(String[] strArr) {
index++;
if (!strArr[index].equals("#")) {
TreeNode node = new TreeNode(-1);
node.val = Integer.parseInt(strArr[index]);
node.left = deserializeHelper(strArr);
node.right = deserializeHelper(strArr);
return node;
}
return null;
}
}
2、非遞迴
import java.util.Queue;
import java.util.LinkedList;
public class Solution {
String Serialize(TreeNode root) {
if(root == null)
return "";
StringBuffer sb = new StringBuffer();
Queue<TreeNode> queue = new LinkedList<>();
queue.offer(root);
TreeNode cur;
while(!queue.isEmpty()){
cur = queue.poll();
if(cur != null){
queue.offer(cur.left);
queue.offer(cur.right);
sb.append(cur.val+",");
}else{
sb.append("#,");
}
}
//去掉末尾逗號
if(sb.length() != 0){
sb.deleteCharAt(sb.length()-1);
}
return sb.toString();
}
TreeNode Deserialize(String str) {
TreeNode head = null;
if(str == null || str.length() == 0) {
return head;
}
String[] nodes = str.split(",");
TreeNode[] treeNodes = new TreeNode[nodes.length];//初始化為null並未建立、分配記憶體
// 1、建立結點
for(int i=0; i<nodes.length; i++){
if(!nodes[i].equals("#")) {
treeNodes[i] = new TreeNode(Integer.parseInt(nodes[i]));
}
}
// 2、將結點連結形成二叉樹
for(int i=0, j = 1; j < treeNodes.length; i++){
if(treeNodes[i] != null){
treeNodes[i].left = treeNodes[j++];
treeNodes[i].right = treeNodes[j++];
}
}
return treeNodes[0];
}
}