zoukankan      html  css  js  c++  java
  • 二叉树的序列化和反序列化

    题目要求:

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

     

    二叉树的序列化和反序列化,特别有意思的一个题目,最近突然发现用好递归真的可以非常优雅的写好代码!

    那将是我毕生追求的目标!---------------->尽管现状并不尽如人意,可是多磨炼一下自己有什么不好呢?

    之所以选这个题目进行整理,是因为二叉树的序列化和反序列化都用到了递归的思想,而且结合了二叉树的前序遍历,我觉得非常有意思,为了加强自己的记忆,写出来

    大家一起交流吧!

     首先画一个简单的树的模型一起看一下:

    首先看序列化部分的代码:

    String Serialize(TreeNode root)
    {
        if(root==null)
              return "#";
        return root.val + " "+Serialize(root.left)+" "+Serialize(root.right);              
    }
    

     序列化部分的代码比较简单,我们画一幅树一下子就可以理解,我觉得树的前序遍历过程本身就是一个递归的思想,可以回顾一下我们脑子是如何写一棵树的前序遍历的

    1--->2-->4-->5--->3-->6-->7 !就是树的完整的前序遍历的过程,当我们进到左子树的时候,本身也是将上一个的程序压如脑栈!然后左子树根节点为根节点,继续遵循中左右的原则进行排序吧!

    所以序列化的代码其实很简单:

    1先是递归结束的条件  ---> if(root==null) 那么就return"#";

    2 如果根节点不是null的话,那么就遵循着前序遍历的条件输出 root.val+" "+Serialize(root.left)+" "+Serialize(root.right); !!!跟人写前序遍历的时候的思维完全一致!

    接下来看反序列化的代码:

    String dstr="";
     TreeNode Deserialize(String str) {
            dstr = str;
            return deserialize();
        }
    
        private TreeNode deserialize() {
            int index = dstr.indexOf(" ");
            String Node = index==-1?dstr:dstr.substring(0,index);
            dstr = index==-1?"":dstr.substring(index+1);
    
            if(Node.equals("#"))//一定要注意字符串的相等用equals来判断不能用==
                return null;
            int value = Integer.parseInt(Node);
            TreeNode t = new TreeNode(value);
            t.left  = deserialize();
            t.right = deserialize();
            return t;
        }

    反序列化的代码也用到了递归的思想,上面那棵树,我们写一下它的序列化的结构是:

    1-->2-->4-->#-->#-->5-->#-->#-->3-->6-->#-->#-->7-->#-->#

    #号代表的就是null!那么我们来分析一下这个代码,

    首先需要明确 序列化之后的代码是用" "进行分隔的,所以我们就是要找int index= dstr.indexOf(" ");这样分成能找到和找不到两种情况

    如果index=-1说明找不到,那么String Node = dstr,找不到说明只有一个Node全部是value,如果找到了就切分substring(0,index)--->index取不到刚好是一个value

    然后我们需要将全局的dstr进行切分,也就是说如果你已经把1这个值取出来了,需要切掉!dstr = index==-1?"":dstr.substring(index+1);//从这个空格的下一个字符开始,刚好是下一个value;

    之后就是新建TreeNode的节点,然后进行树的构造过程!

    t.left = deserialize();

    t.right = deserialize();

    return t;

    可以发现反序列化真的和序列化产生的字符串配合的十分恰当,让人 感叹递归的神奇之处!

  • 相关阅读:
    CSLA.Net 3.0.5 项目管理示例 业务基类 Project.cs
    为什么我要写博客
    LINQ 标准的查询操作符 过滤 where、index1、OfType
    LINQ 概述和演变
    sl中几个简单变量的获取
    Rails存储库从SVN转向Git
    showcase测试界面
    Silverlight读取xml
    向silverlight传递自定义参数
    RadRails1.0降临——增加Profiler、CallGraph Analyzer和Rails Shell等新特性
  • 原文地址:https://www.cnblogs.com/kerwins-AC/p/11592085.html
Copyright © 2011-2022 走看看