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. selenium常用的API(七)判断元素是否可见

    web页面不可见的元素虽不在页面上显示,但是存在于DOM树中,这些元素webdriver也能找到. element.is_displayed()方法可以判断元素是否在页面上显示,如果显示返回True, ...

  2. datebox设置默认时间

    1. html代码: <input id="txtBeginTime" class="easyui-datebox" data-options=" ...

  3. postgres高可用学习篇三:haproxy+keepalived实现postgres负载均衡

    环境: CentOS Linux release 7.6.1810 (Core) 内核版本:3.10.0-957.10.1.el7.x86_64 node1:192.168.216.130 node2 ...

  4. SQL中的trim函数

    Oracle TRIM函数是很常见的函数,下面对Oracle TRIM函数的语法作了详尽的阐述说明,希望可以让您对Oracle TRIM函数有更深的认识. 如果提到Oracle TRIM函数,最简单的 ...

  5. Refactoring open source business models

    https://opensource.com/business/16/4/refactoring-open-source-business-models They say you never forg ...

  6. JS判断某变量是否为某数组中的一个值的3种方法

    1.正则表达式 js 中判断某个元素是否存在于某个 js 数组中,相当于 PHP 语言中的 in_array 函数. 1 Array.prototype.in_array = function (e) ...

  7. Codeforces Round #605 (Div. 3) C. Yet Another Broken Keyboard

    链接: https://codeforces.com/contest/1272/problem/C 题意: Recently, Norge found a string s=s1s2-sn consi ...

  8. 基于虚拟机+Ubuntu1604的ROS-kinetic配置流程

    简单记录一下配置的过程 先换源,以阿里源为例 备份原有源 sudo cp /etc/apt/sources.list /etc/apt/sources_init.list 编辑源文件 sudo ged ...

  9. Expectation Maximization Algorithm

    期望最大化算法EM. 简介 EM算法即期望最大化算法,由Dempster等人在1976年提出[1].这是一种迭代法,用于求解含有隐变量的最大似然估计.最大后验概率估计问题.至于什么是隐变量,在后面会详 ...

  10. 2019.12.11 java程序中几种常见的异常以及出现此异常的原因

    1.java.lang.NullpointerException(空指针异常) 原因:这个异常经常遇到,异常的原因是程序中有空指针,即程序中调用了未经初始化的对象或者是不存在的对象. 经常出现在创建对 ...