LeetCode HOT 100 —— 297.二叉树的序列化与反序列化

题目

序列化是将一个数据结构或者对象转换为连续的比特位的操作,进而可以将转换后的数据存储在一个文件或者内存中,同时也可以通过网络传输到另一个计算机环境,采取相反方式重构得到原数据。

请设计一个算法来实现二叉树的序列化与反序列化。这里不限定你的序列 / 反序列化算法执行逻辑,你只需要保证一个二叉树可以被序列化为一个字符串并且将这个字符串反序列化为原始的树结构。

提示: 输入输出格式与 LeetCode 目前使用的方式一致,详情请参阅 LeetCode
序列化二叉树的格式。你并非必须采取这种方式,你也可以采用其他的方法解决这个问题。

在这里插入图片描述
在这里插入图片描述

思路

方法一:DFS | 深度优先搜索

(1)序列化:

  1. 采用递归的思想,遍历选择前序遍历,是因为 根∣左∣右 的打印顺序,在反序列化时更容易定位出根节点的值。
  2. 遇到 null 节点也要翻译成特定符号,反序列化时才知道这里是 null,这里用"X"表示null

(2)反序列化:

  1. 定义函数 buildTree 用于还原二叉树,传入由序列化字符串转成的 list 数组
  2. 逐个 poplist 的首项,构建当前子树的根节点,顺着 list,构建顺序是根节点→左子树→右子树
  3. 如果弹出的字符为 “X”,则返回 null 节点。
  4. 如果弹出的字符是数值,则创建root节点,并递归构建root的左右子树,最后返回root。

java代码如下:

class Codec{
	//序列化
	public String serialize(TreeNode root){
		if(root == null){
			return "X,";
		}
		String left = serialize(root.left);
		String right = serialize(root.right);
		return root.val + "," + left + right;
	}
	//反序列化
	public TreeNode deserialize(String data){
		String[] nodes = data.split(",");
		Queue<String> queue = new ArrayDeque<>(Arrays.asList(nodes));//队列用来存放列表形式的节点
		return buildTree(queue);
	}
	
	public TreeNode buildTree(Queue<String> queue){
		String value = queue.poll();
		if(value.equals("X")){
			return null;
		}
		TreeNode node = new TreeNode(Integer.parseInt(value));//将字符串转化成数字,Integer.parseInt()作用是将String转换成Int,注意区分Integer.parseInt()和Integer.valueOf(),二者都是将String转换为Int,但是Integer.parseInt()返回的是原子类型int,而Integer.valueOf()返回的是封装的Integer对象。
		node.left = buildTree(queue);
		node.right = buildTree(queue);
		return node;
	}
}

方法二:BFS | 广度优先搜索

(1)序列化:

维护一个队列,初始让根节点入列,考察出列节点:

  1. 如果出列的节点是 null,将符号 "X" 推入 res 数组。
  2. 如果出列的节点是数值,将节点值推入数组 res,并将它的左右子节点入列。
  3. 子节点 null 也要入列,它对应 "X",要被记录,只是它没有子节点可入列。
  4. 入列、出列…直到队列为空,就遍历完所有节点,res构建完毕,转成字符串就好。

(2)反序列化:

依然先转成list数组,用一个指针 cur 从第二项开始扫描,即将list数组中的节点放入队列,然后根据队列还原二叉树

  1. 起初,用list[0]构建根节点,并让根节点入列。
  2. 节点出列,此时 cur 指向它的左子节点值,cur+1 指向它的右子节点值。
  3. 如果子节点值是数值,则创建节点,并认 之前出列的节点 为父亲,同时自己也是父亲,入列。
  4. 如果子节点值为 "X",什么都不用做,因为出列的父亲的 leftright 本来就是 null

java代码如下:

public class Codec {

    // 序列化
    public String serialize(TreeNode root) {
        if (root == null) {
            return "";
        }
        StringBuilder sb = new StringBuilder();
        Queue<TreeNode> queue = new LinkedList<>();
        queue.offer(root);
        while (!queue.isEmpty()) {
            TreeNode node = queue.poll();
            if (node == null) {
                sb.append("X,");
            } else {
                sb.append(node.val + ",");
                queue.offer(node.left);
                queue.offer(node.right);
            }
        }
        return sb.toString();
    }

    // 反序列化
    public TreeNode deserialize(String data) {
        if (data == "") {
            return null;
        }
        Queue<String> nodes = new ArrayDeque<>(Arrays.asList(data.split(",")));
        TreeNode root = new TreeNode(Integer.parseInt(nodes.poll()));
        Queue<TreeNode> queue = new ArrayDeque<>();
        queue.offer(root);//根节点入列
        while (!queue.isEmpty()) {
            TreeNode node = queue.poll();//根节点出列
            String left = nodes.poll();//出左子节点
            String right = nodes.poll();//出右子节点
            if (!left.equals("X")) {//如果左子节点不为空,则入列
                node.left = new TreeNode(Integer.parseInt(left));
                queue.add(node.left);
            }
            if (!right.equals("X")) {//如果右子节点不为空,入列
                node.right = new TreeNode(Integer.parseInt(right));
                queue.add(node.right);
            }
        }
        return root;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

HDU-五七小卡

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值