一般使用的前序、中序、後序、層序遍歷記錄的二叉樹的信息不完整,即惟一的輸出序列可能對應着多種二叉樹可能性。node
能夠發現規律
序列化 使用層序遍歷實現。反序列化 經過以上遞推公式反推各節點在序列中的索引,進而實現。
序列化和反序列化數組
/** * Definition for a binary tree node. * public class TreeNode { * int val; * TreeNode left; * TreeNode right; * TreeNode(int x) { val = x; } * } */ public class Codec { // Encodes a tree to a single string. //這個是序列化 public String serialize(TreeNode root) { //利用隊列進行打印,而且須要把null的也打印出來 if(root == null) return "[]";//要注意方法的返回類型是String StringBuilder res = new StringBuilder("[");//定義一個字符串緩衝流先把左側括號加進去 //定義一個隊列用於加入字符串,而且還要先把根節點加進去,也能夠不加後面單寫一行加 Queue<TreeNode> queue = new LinkedList<>() {{ add(root); }}; while(!queue.isEmpty()){ //poll從隊列頭部刪除一個元素。 隊列是空的時候會返回null TreeNode node = queue.poll(); //若是當前節點不是空的就加入字符串 if(node != null) { //而後出棧的節點的值加入字符緩衝流對象 還要記得加都好,時刻記得這是字符串 res.append(node.val+","); //而後把當前節點的左右節點繼續入棧 queue.add(node.left); queue.add(node.right); }else{ res.append("null,");}//若是是空的也要加入null } //按照層排列完畢了 res.deleteCharAt(res.length() - 1);//要把最後一個字符串後面一塊兒的那個逗號刪掉 res.append("]");//刪掉以後再把數組的另外一半字符串加到上面 return res.toString();//而後再把字符緩衝流變成字符串 } // Decodes your encoded data to tree. //這個是反序列化 public TreeNode deserialize(String data) { //反序列化就是把輸入的字符串再換成節點 if(data.equals("[]") ) return null; //將輸入的一長串字符串用,裁出來取1是去掉一開始的0索引下的[符號 String[] str = data.substring(1,data.length() - 1).split(","); //由於序列化也是一層一層的,因此第一個字符就是根節點 TreeNode root = new TreeNode(Integer.parseInt(str[0]));//將字符串裏的數字字符轉化成數字再變成節點 //定義一個鏈表,先把根節點存進去 Queue<TreeNode> queue = new LinkedList<>() {{ add(root); }}; int i = 1; while(!queue.isEmpty()){ //poll從隊列頭部刪除一個元素。 隊列是空的時候會返回null TreeNode node = queue.poll(); //若是下一個字符的值不是null if(!str[i].equals("null")){ //那當前節點的左節點 就是這個值 node.left = new TreeNode(Integer.parseInt(str[i])); //而後再把當前節點的左節點加進去 queue.add(node.left); } i++; if(!str[i].equals("null")){ //那當前節點的左節點 就是這個值 node.right = new TreeNode(Integer.parseInt(str[i])); //而後再把當前節點的左節點加進去 queue.add(node.right); } i++; } return root; } } // Your Codec object will be instantiated and called as such: // Codec codec = new Codec(); // codec.deserialize(codec.serialize(root));
還有一個速度比較快的答案,用了遞歸app
/** * Definition for a binary tree node. * public class TreeNode { * int val; * TreeNode left; * TreeNode right; * TreeNode(int x) { val = x; } * } */ public class Codec { // Encodes a tree to a single string. public String serialize(TreeNode root) { StringBuilder sb = new StringBuilder(); serialize(root, sb); return sb.toString(); } public void serialize(TreeNode root, StringBuilder sb){ if(root == null){ sb.append("null").append(","); return; } sb.append(root.val).append(","); serialize(root.left,sb); serialize(root.right,sb); } // Decodes your encoded data to tree. public TreeNode deserialize(String data) { if(data == null || data.length() == 0) return null; String[] s = data.split(","); LinkedList<String> nodes = new LinkedList<>(); for(String str : s){ nodes.addLast(str); } return deserialize(nodes); } public TreeNode deserialize(LinkedList<String> nodes){ if(nodes.isEmpty()) return null; String first = nodes.removeFirst(); if(first.equals("null")) return null; TreeNode root = new TreeNode(Integer.parseInt(first)); root.left = deserialize(nodes); root.right = deserialize(nodes); return root; } } // Your Codec object will be instantiated and called as such: // Codec codec = new Codec(); // codec.deserialize(codec.serialize(root));