您的位置:首页 > 其它

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

2018-03-05 14:04 483 查看

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 [code]"[1,2,3,null,null,4,5]"
[/code]

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 题目汇总

  

 

 

 

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: