本文已参与「新人创作礼」活动,一起开启掘金创作之路。
一、二叉树的序列化与反序列化
1、分析
其实可以利用二叉树的不同遍历方式记录每个节点的值,用特殊符号表示空节点,最后用字符串的形式保存遍历的结果。然后在反序列的过程中,再按照相同的遍历顺序思路还原即可。这里分别采用了前序遍历和后序遍历解法。
2、代码
(1)前序遍历
# Definition for a binary tree node.
# class TreeNode(object):
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Codec:
def serialize(self, root):
"""Encodes a tree to a single string.
:type root: TreeNode
:rtype: str
"""
nodes = [] #保留前序遍历的结果
def helper(node):
if not node: #用‘#’表示空节点
nodes.append('#')
return
nodes.append(str(node.val)) #以字符的形式存放
helper(node.left)
helper(node.right)
helper(root)
return ','.join(nodes) #整体遍历结果以字符串形式返回
def deserialize(self, data):
"""Decodes your encoded data to tree.
:type data: str
:rtype: TreeNode
"""
nodes = data.split(',') #首先将字符串形式拆解为list形式方便后续操作
def helper(nodes):
if not nodes: #若数组为空证明没有其他节点了返回None
return None
first = nodes.pop(0) #由于存放的是前序遍历的结果,数组的首位就是根节点
if first=='#': #判断是否为空,若为空返回None
return None
root = TreeNode(int(first)) #若不是空姐点,则构造当前节点
root.left = helper(nodes) #递归的方法构造该节点的左子树和右子树
root.right = helper(nodes)
return root
return helper(nodes)
# Your Codec object will be instantiated and called as such:
# ser = Codec()
# deser = Codec()
# ans = deser.deserialize(ser.serialize(root))
JS
/**
* Definition for a binary tree node.
* function TreeNode(val) {
* this.val = val;
* this.left = this.right = null;
* }
*/
/**
* Encodes a tree to a single string.
*
* @param {TreeNode} root
* @return {string}
*/
var serialize = function(root) {
let nodes = []
var helper = function(root){
if(root===null){
nodes.push('#');
return
}
nodes.push(String(root.val));
helper(root.left);
helper(root.right);
}
helper(root);
return nodes.join(",");
};
/**
* Decodes your encoded data to tree.
*
* @param {string} data
* @return {TreeNode}
*/
var deserialize = function(data) {
let nodes = data.split(",");
var helper = function(nodes){
if(nodes.length===0){
return null;
}
let first = nodes.shift();
if(first=='#'){
return null;
}
let root = new TreeNode(Number(first)); //特别注意js的构造函数用new调用啊!!!python写多了,导致找整个bug好半天
root.left = helper(nodes);
root.right = helper(nodes);
return root;
}
return helper(nodes);
};
/**
* Your functions will be called as such:
* deserialize(serialize(root));
*/
(2)后序遍历
# Definition for a binary tree node.
# class TreeNode(object):
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Codec:
def serialize(self, root):
"""Encodes a tree to a single string.
:type root: TreeNode
:rtype: str
"""
nodes = [] #存放后续遍历结果
def helper(root):
if root:
helper(root.left)
helper(root.right)
nodes.append(str(root.val))
else:
nodes.append('#') #用‘#’表示空节点
helper(root)
return ','.join(nodes) #整体序列化结果用字符串表示
def deserialize(self, data):
"""Decodes your encoded data to tree.
:type data: str
:rtype: TreeNode
"""
nodes = data.split(',') #拆开成为list格式,方便操作
def helper(nodes):
if not nodes:
return None
first = nodes.pop() #注意到后续遍历中根节点在list的末尾位置
if first=='#':
return None
root = TreeNode(int(first)) #因为使用的是后续遍历,我们逆序构造,先右子树,后左子树
root.right = helper(nodes)
root.left = helper(nodes)
return root
return helper(nodes)
# Your Codec object will be instantiated and called as such:
# ser = Codec()
# deser = Codec()
# ans = deser.deserialize(ser.serialize(root))
JS
/**
* Definition for a binary tree node.
* function TreeNode(val) {
* this.val = val;
* this.left = this.right = null;
* }
*/
/**
* Encodes a tree to a single string.
*
* @param {TreeNode} root
* @return {string}
*/
var serialize = function(root) {
let nodes = [];
var helper = function(root){
if(root!==null){
helper(root.left);
helper(root.right);
nodes.push(String(root.val));
}else{
nodes.push('#');
}
}
helper(root);
return nodes.join(',');
};
/**
* Decodes your encoded data to tree.
*
* @param {string} data
* @return {TreeNode}
*/
var deserialize = function(data) {
let nodes = data.split(',');
var helper = function(nodes){
if(nodes.length==0){
return null;
}
let first = nodes.pop();
if(first==='#'){
return null;
}
let root = new TreeNode(Number(first));
root.right = helper(nodes);
root.left = helper(nodes);
return root;
}
return helper(nodes);
};
/**
* Your functions will be called as such:
* deserialize(serialize(root));
*/