首页 > 其他分享 >【剑指Offer】61、序列化二叉树

【剑指Offer】61、序列化二叉树

时间:2023-08-17 23:57:02浏览次数:42  
标签:结点 遍历 TreeNode null 61 二叉树 序列化

【剑指Offer】61、序列化二叉树

题目描述:

请实现两个函数,分别用来序列化和反序列化二叉树。

解题思路:

序列化是指将结构化的对象转化为字节流以便在网络上传输或写到磁盘进行永久存储的过程。反序列化是指将字节流转回结构化的对象的过程,是序列化的逆过程。

受第4题:重建二叉树的启发https://www.cnblogs.com/bujidao1128/p/17625931.html,我们知道从前序遍历和中序遍历序列中可以构造出一棵二叉树,因此将一棵二叉树序列化为一个前序遍历序列和一个中序遍历序列,然后在反序列化时用第四题的思路重建二叉树。

这种思路是可行的,但是存在两个缺点:一是该方法要求二叉树中不能有重复的结点(比如我们通过前序知道根是1,若有重复的结点无法在中序序列中定位根的位置);二是只有当两个序列中所有的数据都读出后才能开始反序列化,如果两个遍历序列是从一个流中读出来的,那么可能需要等待较长的时间。

因此,这里我们采用另外一种方法,即只根据前序遍历的顺序来进行序列化,前序遍历是从根结点开始,在遍历二叉树碰到null指针时,就将其序列化为一个特殊字符,比如$,另外,结点的数值之间用一个特殊字符(比如,)进行分隔。比如对于以下的树,序列化为字符串:"1,2,4,$,$,$,3,5,$,$,6,$,$"

然后我们可以以"1,2,4,$,$,$,3,5,$,$,6,$,$"为例来分析反序列化的过程,第一个读出1,这是根结点的值,然后读出2,这是根结点的左孩子,同样接下来的4是值为2的结点的左孩子结点;接下来读出两个“”,说明值为4的结点左右孩子都是null,这是一个叶结点。然后回到值为2的结点,重建它的右子树,由于下一个字符是“
”,说明值为2的结点的右孩子结点为null,这个结点的左右子树都重建完毕,接下来再次回溯就到了根结点,所以,左子树重构完毕。

由于下一个数字是3,所以右子树的根结点值为3,左结点时一个值为5的叶结点(因为接下来的三个字符是5,$,$),同理右结点时一个值为6的结点。至此,重构完毕,反序列化完成。

序列化比较简单,就是一个前序遍历的过程,而反序列化也不难发现,实际就是一个递归解决每个子树的问题,详见以下代码实现。

编程实现(Java):

public class TreeNode {
    int val = 0;
    TreeNode left = null;
    TreeNode right = null;

    public TreeNode(int val) {
        this.val = val;
    }
}
public class Solution {
    String Serialize(TreeNode root){
        if(root==null)
            return "#,";
        String res="";
        res+=root.val+",";   //前序遍历,根左右
        res+=Serialize(root.left);
        res+=Serialize(root.right);
        return res;
    }

    //反序列化
    int start=-1;
    TreeNode Deserialize(String str){
        if(str==null || str.length()==0)
            return null;
        String[] strArr=str.split(",");
        return Deserialize(strArr);
    }
    TreeNode Deserialize(String[] strArr){
        start++;
        if(start>=strArr.length || strArr[start].equals("#"))
            return null;
        TreeNode cur=new TreeNode(Integer.valueOf(strArr[start]));
        cur.left=Deserialize(strArr);
        cur.right=Deserialize(strArr);
        return cur;
    }
}

标签:结点,遍历,TreeNode,null,61,二叉树,序列化
From: https://www.cnblogs.com/bujidao1128/p/17639226.html

相关文章

  • 平衡二叉树
    110.平衡二叉树-力扣(LeetCode)确定思路如果左右子树都是平衡二叉树,并且左右子树的高度相差不超过1,那么就是平衡二叉树,如果左子树不是平衡二叉树也就不用对右子树进行递归了确定终止条件应该是遍历到叶子节点,因为叶子节点不能构成二叉树了,因为就没有再往下遍历的必要了——......
  • 剑指 Offer 07. 重建二叉树(中等)
    题目:classSolution{//本题思路:利用中序遍历,从前序遍历中找到左、右子树的根节点public:unordered_map<int,int>dic;//创建字典,映射当前根节点在中序遍历中的位置,以便于划分当前根节点的左右子树vector<int>preorder;//即下面的this->preorder......
  • [代码随想录]Day20-二叉树part09
    题目:669.修剪二叉搜索树思路:遍历到的值小于最小值,说明左子树里的所有节点都小于最小值,舍弃左子树。遍历到的值大于最大值,说明右子树里的所有节点都大于最大值,舍弃右子树。如果在范围内,就拼接左右子树然后返回节点代码:/***Definitionforabinarytreenode.*typeTr......
  • Feign接口返回值加多层泛型,但没有反序列化彻底
    1、问题描述接口返回值加多层泛型,但没有反序列化彻底2、问题原因jackson-databindjar包版本的问题我们之前用的是2.11.2,这个版本有bug,版本变成2.11.3就好了......
  • asp.net core Webapi中返回400错误中的‘Null集合属性序列化Json’情况
    当序列化Json时,有集合类型的属性的值为Null,则序列化后的json就有问题,不能通过asp.netcoreWebApi的校验 解决方法是:只需要对集合默认初始化即可......
  • PHP反序列化漏洞笔记(一):初识序列化
    PHP类与对象类:一组共享相同结构和和行为的对象集合对象:类的实例使用new的关键字Phpmagic函数在PHP中,魔术方法(MagicMethods)是一组特殊的函数,它们以双下划线(__)作为前缀来命名。这些函数在特定的情况下会自动调用,以执行一些特定的操作。以下是一些常用的魔术方法:实践:自动化的操作:......
  • 代码随想录算法训练营第十八天| 513.找树左下角的值 112. 路径总和 106.从中序与
     找树左下角的值     卡哥建议:本地递归偏难,反而迭代简单属于模板题, 两种方法掌握一下   题目链接/文章讲解/视频讲解:https://programmercarl.com/0513.%E6%89%BE%E6%A0%91%E5%B7%A6%E4%B8%8B%E8%A7%92%E7%9A%84%E5%80%BC.html   做题思路:   题目说......
  • 代码随想录算法训练营第十七天| 110.平衡二叉树 257. 二叉树的所有路径 404.左叶子
     卡哥建议:迭代法,大家可以直接过,二刷有精力的时候 再去掌握迭代法。  110.平衡二叉树 (优先掌握递归)   卡哥建议:再一次涉及到,什么是高度,什么是深度,可以巩固一下。   题目链接/文章讲解/视频讲解:https://programmercarl.com/0110.%E5%B9%B3%E8%A1%A1%E4%BA%8C%......
  • 【剑指Offer】58、对称的二叉树
    【剑指Offer】58、对称的二叉树题目描述:请实现一个函数,用来判断一颗二叉树是不是对称的。注意,如果一个二叉树同此二叉树的镜像是同样的,定义其为对称的。解题思路:本题判断一棵树是不是对称的,和第18题可以对比分析:二叉树的镜像,和LeetCode第101题:101.对称二叉树是同一道题。解......
  • 【剑指Offer】59、按之字形顺序打印二叉树
    【剑指Offer】59、按之字形顺序打印二叉树题目描述:请实现一个函数按照之字形打印二叉树,即第一行按照从左到右的顺序打印,第二层按照从右至左的顺序打印,第三行按照从左到右的顺序打印,其他行以此类推。解题思路:这道题仍然是二叉树的遍历,相当于层次遍历,可以和第22题:从上往下打印二......