剑指offer37:序列化二叉树

一 题目:序列化二叉树

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

二叉树的反序列化是指:根据某种遍历顺序得到的序列化字符串结果str,重构二叉树。
在这里插入图片描述

二 思路分析
1 序列化
  • 可以使用前序遍历来将节点保存到字符串中,但是为了反序列化,需要以满二叉树的方式保存,那么没有的地方我们就用"#"来表示!

  • 分为多种情况,

    • 情形一:该节点没有子节点

      此时,返回的字符串为:“节点的value, #, #”

    • 情形二:该节点只有一个左子节点

      返回的字符串为:“节点的value,节点的左子节点的value, #”

    • 情形三:该节点只有一个右子节点

      返回的字符串为:“节点的value,#, 节点的右子节点的value”

  • 递归的方法。不用去追究每次递归的细节,只需要关注总问题和子问题之间的关系即可。如下代码所示内容,因为不管是总问题还是子问题,都需要将结果保存到字符串中,那么这里就巧妙的使用了StringBuilder(),将子问题遍历的结果保存到字符串中,然后再使用StringBuilder的ad方法,添加到总问题中。就是这样简单!

  • 代码如下:

  public String Serialize(TreeNode root) {
        StringBuilder sb = new StringBuilder();
        if (root == null) {
            // 递归终止条件内容
            sb.append("#,");
            return sb.toString(); 
        }
			
        sb.append(root.val + ",");
        sb.append(Serialize(root.left));
        sb.append(Serialize(root.right));
        return sb.toString(); // 方法执行结束时的返回的内容!
    }

在这里插入图片描述

经过上述步骤后,字符串中保存的是:"1,2,#,3,#,#,4,5,#,#,#,"

2 反序列化
  • 假设只存在一个结点和其左右两个子节点内容,那么很简单内可以使用一下代码搞定

    node = new TreeNode(str[0])
    node.left = new TreeNode(str[1])
    node.right = new TreeNode(str[2])
    
  • 但是现在并不是一个简单的二叉树,并且字符串中还包含其他的内容,尝试用递归的方法来解决这个问题。首先用index来索引字符,然后还有判断是否为"#",具体过程如下

    • 先从1开始,创建一个root节点
    • 根节点的左子节点,通过遍历第二个字符来获取
    • 根节点的右子节点,等到左子树遍历完了之后,在根据index来获取
    • 总问题和子问题之间,我们使用返回的节点来连接。

    具体代码如下:

        public TreeNode Deserialize(String str) {
            index++; //每次调用方法,index自增1
            String[] strr = str.split(",");
            TreeNode node = null;
            if (!strr[index].equals("#")) {
                node = new TreeNode(Integer.valueOf(strr[index]));
                node.left = Deserialize(str);
                node.right = Deserialize(str);
            }
            return node; //最后返回的是根节点的内容
        }
    
三 代码实现
public class Solution43 {
    int index = -1; // 计数变量
    public String Serialize(TreeNode root) {
        StringBuilder sb = new StringBuilder();
        if (root == null) {
            sb.append("#,");
            return sb.toString();
        }

        sb.append(root.val + ",");
        sb.append(Serialize(root.left));
        sb.append(Serialize(root.right));
        return sb.toString();
    }

    public TreeNode Deserialize(String str) {
        index++;
        String[] strr = str.split(",");
        TreeNode node = null;
        if (!strr[index].equals("#")) {
            node = new TreeNode(Integer.valueOf(strr[index]));
            node.left = Deserialize(str);
            node.right = Deserialize(str);
        }
        return node;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值