JZ61 序列化二叉树

描述

请实现两个函数,分别用来序列化和反序列化二叉树,不对序列化之后的字符串进行约束,但要求能够根据序列化之后的字符串重新构造出一棵与原二叉树相同的树。

二叉树的序列化是指:把一棵二叉树按照某种遍历方式的结果以某种格式保存为字符串,从而使得内存中建立起来的二叉树可以持久保存。序列化可以基于先序、中序、后序、层序的二叉树等遍历方式来进行修改,序列化的结果是一个字符串,序列化时通过 某种符号表示空节点(#),以 ! 表示一个结点值的结束(value!)。
二叉树的反序列化是指:根据某种遍历顺序得到的序列化字符串结果str,重构二叉树。

例如,可以根据层序遍历并特定标志空结点的方案序列化,也可以根据满二叉树结点位置的标号规律来序列化,还可以根据先序遍历和中序遍历的结果来序列化。

假如一棵树共有 2 个结点, 其根结点为 1 ,根结点右子结点为 2 ,没有其他结点。按照上面第一种说法可以序列化为“1,#,2,#,#”,按照上面第二种说法可以序列化为“{0:1,2:2}”,按照上面第三种说法可以序列化为“1,2;2,1”,这三种序列化的结果都包含足以构建一棵与原二叉树完全相同的二叉树的信息。

这题目看描述就知道是困难模式了。而且讨论组关于Python版本很少。

按照讨论组其他人的说法,有先序遍历和层序遍历两种解法。

可以使用先序遍历的方式序列化二叉树,用'#'表示空,'!'标志一个结点值的结束,序列化时通过先序遍历的顺序,当遇到非空节点时取出其值的字符串表示再在后面加个'!'标示着结尾,以便我们反序列化时确定节点的值。

采用与前序遍历相似的做法,用'!'标示数值的结束,用'#'标示空节点,序列化的过程很简单,用队列完成层序遍历,先将根节点入队,然后每次出队一个元素就尝试将其左右儿子加入队列,若无就在字符串后加上'#',否则加上"val" + "!"即可

反序列化相当于是一个重构的逆过程。

下面的代码没有用!表示数值的结束,应该是用的题目中描述的第一种说法:可以序列化为“1,#,2,#,#”。

来自题解:https://blog.nowcoder.net/n/758e42d8b9be44f58dc838ccdda21019?f=comment

#主要是递归的思路
class Solution:
    ss = []
    def Serialize(self, root):
        if root is None:
            return '#,'
        return str(root.val) +','+ self.Serialize(root.left) + self.Serialize(root.right)

    def Deserialize(self, s):
        if len(s)==0:
            return None
        if s[0] == '#':
            return None
        self.ss = s.split(',')
        return self.reconstruct()

    def reconstruct(self):
        val = self.ss[0]
        if val == '#':
            self.ss = self.ss[1:]
            return None
        val = int(val)
        root = TreeNode(val)
        self.ss = self.ss[1:]
        root.left = self.reconstruct()
        root.right = self.reconstruct()
        return root

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值