序列化是將一個數據結構或者對象轉換爲連續的比特位的操做,進而能夠將轉換後的數據存儲在一個文件或者內存中,同時也能夠經過網絡傳輸到另外一個計算機環境,採起相反方式重構獲得原數據。java
請設計一個算法來實現二叉樹的序列化與反序列化。這裏不限定你的序列 / 反序列化算法執行邏輯,你只須要保證一個二叉樹能夠被序列化爲一個字符串而且將這個字符串反序列化爲原始的樹結構。node
__示例: __git
你能夠將如下二叉樹: 1 / \ 2 3 / \ 4 5 序列化爲 "[1,2,3,null,null,4,5]"
提示: 這與 LeetCode 目前使用的方式一致,詳情請參閱 LeetCode 序列化二叉樹的格式。你並不是必須採起這種方式,你也能夠採用其餘的方法解決這個問題。github
說明: 不要使用類的成員 / 全局 / 靜態變量來存儲狀態,你的序列化和反序列化算法應該是無狀態的。算法
來源:力扣(LeetCode)
連接:https://leetcode-cn.com/problems/serialize-and-deserialize-binary-tree
著做權歸領釦網絡全部。商業轉載請聯繫官方受權,非商業轉載請註明出處。數組
示例提供的只是一個演示,實際序列化成的數據格式和反序列化的邏輯不用與示例一致,只要保證明現的兩個方法可讓數據成功互轉便可;網絡
序列化:按照樹的層逐層序列化,null值序列化爲"null",用","p拼接;
反序列化:用「,」分割得到數組,首個值爲樹的根節點,而後給樹安排左右子節點,仍然是按照BFS的邏輯反向還原便可;數據結構
算法複雜度:app
序列化:直接按照先序遍歷的順序遞歸序列化樹;
反序列化:反向遞歸還原樹,注意左右子樹的還原順序;ui
算法複雜度:
package leetcode; import java.util.Arrays; import java.util.LinkedList; import java.util.Objects; /** * @author ZhouJie * @date 2020年5月3日 下午11:42:01 * @Description: 297. 二叉樹的序列化與反序列化 * */ public class LeetCode_0297 { } //Definition for a binary tree node. class TreeNode_0297 { int val; TreeNode_0297 left; TreeNode_0297 right; TreeNode_0297(int x) { val = x; } } /** * @author ZhouJie * @date 2020年5月3日 下午10:48:39 * @Description: 1-層次遍歷/BFS,使用LinkedList記錄節點; * */ class Codec_297_1 { // Encodes a tree to a single string. public String serialize(TreeNode_0297 root) { if (root == null) { return ""; } LinkedList<TreeNode_0297> queue = new LinkedList<TreeNode_0297>(); StringBuilder sb = new StringBuilder("["); queue.offer(root); while (!queue.isEmpty()) { TreeNode_0297 node = queue.poll(); if (node != null) { sb.append(node.val); queue.offer(node.left); queue.offer(node.right); } else { sb.append("null"); } sb.append(","); } return sb.deleteCharAt(sb.length() - 1).append("]").toString(); } // Decodes your encoded data to tree. public TreeNode_0297 deserialize(String data) { if (data == null || data.isEmpty()) { return null; } String[] nodeArray = data.substring(1, data.length() - 1).split(","); int i = 0; TreeNode_0297 root = buildeNode(nodeArray[i++]); LinkedList<TreeNode_0297> queue = new LinkedList<TreeNode_0297>(); queue.offer(root); while (!queue.isEmpty()) { TreeNode_0297 node = queue.poll(); node.left = buildeNode(nodeArray[i++]); node.right = buildeNode(nodeArray[i++]); if (node.left != null) { queue.offer(node.left); } if (node.right != null) { queue.offer(node.right); } } return root; } private TreeNode_0297 buildeNode(String s) { if (Objects.equals(s, "null")) { return null; } else { return new TreeNode_0297(Integer.valueOf(s)); } } } /** * @author ZhouJie * @date 2020年5月3日 下午11:24:23 * @Description: 2-DFS * */ class Codec_297_2 { // Encodes a tree to a single string. public String serialize(TreeNode_0297 root) { return serialize(root, new StringBuilder()); } private String serialize(TreeNode_0297 root, StringBuilder sb) { if (root == null) { sb.append("null,"); } else { sb.append(root.val).append(","); serialize(root.left, sb); serialize(root.right, sb); } return sb.toString(); } // Decodes your encoded data to tree. public TreeNode_0297 deserialize(String data) { return deserialize(new LinkedList<String>(Arrays.asList(data.split(",")))); } private TreeNode_0297 deserialize(LinkedList<String> list) { String s = list.get(0); list.remove(0); if (Objects.equals(s, "null")) { return null; } else { TreeNode_0297 root = buildeNode(s); root.left = deserialize(list); root.right = deserialize(list); return root; } } private TreeNode_0297 buildeNode(String s) { if (Objects.equals(s, "null")) { return null; } else { return new TreeNode_0297(Integer.valueOf(s)); } } } //Your Codec object will be instantiated and called as such: //Codec codec = new Codec(); //codec.deserialize(codec.serialize(root));