【算法训练】二叉树系列(三)二叉树的序列化与反序列化

137 阅读3分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

一、二叉树的序列化与反序列化

在这里插入图片描述

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));
 */