Serialization is the process of converting a data structure or object into a sequence of bits so that it can be stored in a file or memory buffer, or transmitted across a network connection link to be reconstructed later in the same or another computer environment.

Design an algorithm to serialize and deserialize a binary tree. There is no restriction on how your serialization/deserialization algorithm should work. You just need to ensure that a binary tree can be serialized to a string and this string can be deserialized to the original tree structure.

Example:

You may serialize the following tree:

    1
/ \
2 3
/ \
4 5 as "[1,2,3,null,null,4,5]"

Clarification: The above format is the same as how LeetCode serializes a binary tree. You do not necessarily need to follow this format, so please be creative and come up with different approaches yourself.

Note: Do not use class member/global/static variables to store states. Your serialize and deserialize algorithms should be stateless.

序列化是是指将数据结构或物件状态转换成可取用格式(例如存成档案,存于缓冲,或经由网络中传送),以留待后续在相同或另一台计算机环境中,能恢复原先状态的过程,还原的过程叫做反序列化。比如例子中的把树序列化成数组,还可以由这个数组在反序列化变回树。

根据题目序列化的形式,可以先序遍历的递归或者层序遍历的非递归:

需要接入输入和输出字符串流istringstream和ostringstream,对于序列化,从根节点开始,如果节点存在,则将值存入输出字符串流,然后分别对其左右子节点递归调用序列化函数即可。对于反序列化,先读入第一个字符生成一个根节点,然后再对根节点的左右子节点递归调用去序列化函数即可。

Java:level order traversal

// Encodes a tree to a single string.
public String serialize(TreeNode root) {
if(root==null){
return "";
} StringBuilder sb = new StringBuilder(); LinkedList<TreeNode> queue = new LinkedList<TreeNode>(); queue.add(root);
while(!queue.isEmpty()){
TreeNode t = queue.poll();
if(t!=null){
sb.append(String.valueOf(t.val) + ",");
queue.add(t.left);
queue.add(t.right);
}else{
sb.append("#,");
}
} sb.deleteCharAt(sb.length()-1);
System.out.println(sb.toString());
return sb.toString();
} // Decodes your encoded data to tree.
public TreeNode deserialize(String data) {
if(data==null || data.length()==0)
return null; String[] arr = data.split(",");
TreeNode root = new TreeNode(Integer.parseInt(arr[0])); LinkedList<TreeNode> queue = new LinkedList<TreeNode>();
queue.add(root); int i=1;
while(!queue.isEmpty()){
TreeNode t = queue.poll(); if(t==null)
continue; if(!arr[i].equals("#")){
t.left = new TreeNode(Integer.parseInt(arr[i]));
queue.offer(t.left); }else{
t.left = null;
queue.offer(null);
}
i++; if(!arr[i].equals("#")){
t.right = new TreeNode(Integer.parseInt(arr[i]));
queue.offer(t.right); }else{
t.right = null;
queue.offer(null);
}
i++;
} return root;
}

Java: Preorder traversal

// Encodes a tree to a single string.
public String serialize(TreeNode root) {
if(root==null)
return null; Stack<TreeNode> stack = new Stack<TreeNode>();
stack.push(root);
StringBuilder sb = new StringBuilder(); while(!stack.isEmpty()){
TreeNode h = stack.pop();
if(h!=null){
sb.append(h.val+",");
stack.push(h.right);
stack.push(h.left);
}else{
sb.append("#,");
}
} return sb.toString().substring(0, sb.length()-1);
} // Decodes your encoded data to tree.
public TreeNode deserialize(String data) {
if(data == null)
return null; int[] t = {0};
String[] arr = data.split(","); return helper(arr, t);
} public TreeNode helper(String[] arr, int[] t){
if(arr[t[0]].equals("#")){
return null;
} TreeNode root = new TreeNode(Integer.parseInt(arr[t[0]])); t[0]=t[0]+1;
root.left = helper(arr, t);
t[0]=t[0]+1;
root.right = helper(arr, t); return root;
}

Java:

public class Codec {
private static final String spliter = ",";
private static final String NN = "X"; // Encodes a tree to a single string.
public String serialize(TreeNode root) {
StringBuilder sb = new StringBuilder();
buildString(root, sb);
return sb.toString();
} private void buildString(TreeNode node, StringBuilder sb) {
if (node == null) {
sb.append(NN).append(spliter);
} else {
sb.append(node.val).append(spliter);
buildString(node.left, sb);
buildString(node.right,sb);
}
}
// Decodes your encoded data to tree.
public TreeNode deserialize(String data) {
Deque<String> nodes = new LinkedList<>();
nodes.addAll(Arrays.asList(data.split(spliter)));
return buildTree(nodes);
} private TreeNode buildTree(Deque<String> nodes) {
String val = nodes.remove();
if (val.equals(NN)) return null;
else {
TreeNode node = new TreeNode(Integer.valueOf(val));
node.left = buildTree(nodes);
node.right = buildTree(nodes);
return node;
}
}
}  

Python:

class Codec:

    def serialize(self, root):
def serializeHelper(node):
if not node:
vals.append('#')
else:
vals.append(str(node.val))
serializeHelper(node.left)
serializeHelper(node.right)
vals = []
serializeHelper(root)
return ' '.join(vals) def deserialize(self, data):
def deserializeHelper():
val = next(vals)
if val == '#':
return None
else:
node = TreeNode(int(val))
node.left = deserializeHelper()
node.right = deserializeHelper()
return node
def isplit(source, sep):
sepsize = len(sep)
start = 0
while True:
idx = source.find(sep, start)
if idx == -1:
yield source[start:]
return
yield source[start:idx]
start = idx + sepsize
vals = iter(isplit(data, ' '))
return deserializeHelper()

Python:

class Codec:

    def serialize(self, root):
def doit(node):
if node:
vals.append(str(node.val))
doit(node.left)
doit(node.right)
else:
vals.append('#')
vals = []
doit(root)
return ' '.join(vals) def deserialize(self, data):
def doit():
val = next(vals)
if val == '#':
return None
node = TreeNode(int(val))
node.left = doit()
node.right = doit()
return node
vals = iter(data.split())
return doit()  

C++:

class Codec {
public:
string serialize(TreeNode* root) {
ostringstream out;
serialize(root, out);
return out.str();
} TreeNode* deserialize(string data) {
istringstream in(data);
return deserialize(in);
}
private:
void serialize(TreeNode* root, ostringstream& out) {
if (!root) {
out << "# ";
return;
}
out << root->val << " ";
serialize(root->left, out);
serialize(root->right, out);
} TreeNode* deserialize(istringstream& in) {
string val;
in >> val;
if (val == "#") return nullptr;
TreeNode* root = new TreeNode(stoi(val));
root->left = deserialize(in);
root->right = deserialize(in);
return root;
}
};

C++:

class Codec {
public: string serialize(TreeNode* root) {
ostringstream out;
serialize(root, out);
return out.str();
} TreeNode* deserialize(string data) {
istringstream in(data);
return deserialize(in);
}
private:
enum STATUS {
ROOT_NULL = 0x0,
ROOT = 0x1,
LEFT = 0x2,
RIGHT = 0x4
}; void serialize(TreeNode* root, ostringstream& out) {
char status = 0;
if (root) status |= ROOT;
if (root && root->left) status |= LEFT;
if (root && root->right) status |= RIGHT;
out.write(&status, sizeof(char));
if (!root) return;
out.write(reinterpret_cast<char*>(&(root->val)), sizeof(root->val));
if (root->left) serialize(root->left, out);
if (root->right) serialize(root->right, out);
} TreeNode* deserialize(istringstream& in) {
char status;
in.read(&status, sizeof(char));
if (!status & ROOT) return nullptr;
auto root = new TreeNode(0);
in.read(reinterpret_cast<char*>(&root->val), sizeof(root->val));
root->left = (status & LEFT) ? deserialize(in) : nullptr;
root->right = (status & RIGHT) ? deserialize(in) : nullptr;
return root;
}
};

 

Followup: 如果是 n-ary怎么办?

   

All LeetCode Questions List 题目汇总

  

[LeetCode] 297. Serialize and Deserialize Binary Tree 二叉树的序列化和反序列化的更多相关文章

  1. 297 Serialize and Deserialize Binary Tree 二叉树的序列化与反序列化

    序列化是将一个数据结构或者对象转换为连续的比特位的操作,进而可以将转换后的数据存储在一个文件或者内存中,同时也可以通过网络传输到另一个计算机环境,采取相反方式重构得到原数据.请设计一个算法来实现二叉树 ...

  2. 297. Serialize and Deserialize Binary Tree二叉树的序列化和反序列化(就用Q)

    [抄题]: Serialization is the process of converting a data structure or object into a sequence of bits ...

  3. [leetcode]297. Serialize and Deserialize Binary Tree 序列化与反序列化二叉树

    Serialization is the process of converting a data structure or object into a sequence of bits so tha ...

  4. [LeetCode] Serialize and Deserialize Binary Tree 二叉树的序列化和去序列化

    Serialization is the process of converting a data structure or object into a sequence of bits so tha ...

  5. Leetcode 297. Serialize and Deserialize Binary Tree

    https://leetcode.com/problems/serialize-and-deserialize-binary-tree/ Serialization is the process of ...

  6. [leetcode]297. Serialize and Deserialize Binary Tree一般二叉树的编解码

    由于一般的前序遍历不能唯一的还原出原本你的二叉树,所以要改变一下: 记录二叉树的结构信息,也就是空节点用符号表示 一般的前序遍历只是记录了节点的前后顺序,通过记录空节点,每一层的结构就可以记录下来 解 ...

  7. 【LeetCode】297. Serialize and Deserialize Binary Tree 解题报告(Python)

    [LeetCode]297. Serialize and Deserialize Binary Tree 解题报告(Python) 标签: LeetCode 题目地址:https://leetcode ...

  8. LC 297 Serialize and Deserialize Binary Tree

    问题: Serialize and Deserialize Binary Tree 描述: Serialization is the process of converting a data stru ...

  9. 【LeetCode】297. Serialize and Deserialize Binary Tree

    二叉树的序列化与反序列化. 如果使用string作为媒介来存储,传递序列化结果的话,会给反序列话带来很多不方便. 这里学会了使用 sstream 中的 输入流'istringstream' 和 输出流 ...

随机推荐

  1. jdbc.DataSourceProperties$DataSourceBeanCreationException: Failed to determine a suitable driver class

    java.lang.IllegalStateException: Failed to load ApplicationContext at org.springframework.test.conte ...

  2. ARTS-week6

    Algorithm 给定一个已按照升序排列 的有序数组,找到两个数使得它们相加之和等于目标数.函数应该返回这两个下标值 index1 和 index2,其中 index1 必须小于 index2 Tw ...

  3. 《逆袭团队》第九次团队作业【Beta】Scrum meeting 2

    项目 内容 软件工程 任课教师博客主页链接 作业链接地址 团队作业9:Beta冲刺与团队项目验收 团队名称 逆袭团队 具体目标 (1)掌握软件黑盒测试技术:(2)学会编制软件项目总结PPT.项目验收报 ...

  4. 11.vue-router编程式导航

    页面导航的两种方式 声明式导航:通过点击链接实现导航的方式,叫做声明式导航 例如:普通网页中的链接或vue中的 编程式导航:通过调用JavaScrip形式的API实现导航的方式,叫做编程式导航 例如: ...

  5. 嘉立创制作PCB流程

    现在做板子基本上是选择嘉立创和捷配,今天看一下嘉立创如何下PCB和STM贴片单,改天再写一下捷配的下单 我喜欢用下单助手,比较方便 注意需要把自己的板子的PCB文件用压缩软件生成压缩包文件,名字自己取 ...

  6. UDP网络程序设计

    udp_server #include<stdio.h>#include<sys/socket.h>#include<string.h>#include<ne ...

  7. MintUI引入vue项目以及引入iconfont图标

    官网地址:http://mint-ui.github.io/#!/zh-cn 中文文档:http://mint-ui.github.io/docs/#/zh-cn2 示例展示:http://eleme ...

  8. CF1221F Choose a Square(二维偏序)

    由于y=x,我们可以将点对称过来,以便(x,y)(x<y) 考虑选取正方形(a,a,b,b),点集则为\((a\le x\le y\le b)\),相当于二维数点 将点按x降序,y升序排列,线段 ...

  9. Linux下的nexus数据迁移

    刚到公司没多久,目前公司有两个项目公用一个nexus的maven私服,现在想把两个私服的jar包拆分开: 我在原私服的nexus服务器中, 1.备份原nexus使用命令 完成tar包的压缩 打包完毕后 ...

  10. Eclipse 高亮显示(pydev 编辑 python)

    因为是使用pydev编辑的python,所以需要修改(pydev)的属性. Window->Preferences->General->Editors->Text Editor ...