剑指offer-序列化二叉树

题目描述

  • 请实现两个函数,分别用来序列化和反序列化二叉树
  • 地址: 牛客地址

问题分析

  • 先序遍历序列化和反序列化二叉树
  • 层次遍历序列化和反序列化二叉树

经验教训

  • 序列化时,val后面跟 “!”,用来隔离每一个节点的值,空结点用 “#” 表示
  • 先序遍历如何反序列化的
  • 层次遍历如何序列化和反序列化的

代码实现

  • 先序遍历序列化和反序列化二叉树
    //前序遍历序列化
    String Serialize(TreeNode root) {
        if (root == null) {
            return "#!";
        }
        StringBuffer res = new StringBuffer();
        res.append(root.val).append("!");
        res.append(Serialize(root.left));
        res.append(Serialize(root.right));
        return res.toString();
  }
    //对前序遍历序列化的结果进行反序列化
    TreeNode Deserialize(String str) {
        String[] strArray = str.split("!");
        LinkedList<String> queue = new LinkedList<>();
        for (int i = 0; i < strArray.length; i++) {
            queue.add(strArray[i]);
        }
       return Deserialize(queue);
  }
    TreeNode Deserialize(LinkedList<String> queue) {
        String curString = queue.poll();
        if("#".equals(curString)) {
            return null;
        }
        TreeNode root = new TreeNode(Integer.valueOf(curString));
        root.left = Deserialize(queue);
        root.right = Deserialize(queue);
        return root;
    }
  • 层次遍历序列化和反序列化二叉树
    String Serialize(TreeNode root) {
        if (root == null) {
            return "#!";
        }
        StringBuffer res = new StringBuffer();
        LinkedList<TreeNode> queue = new LinkedList<>();
        queue.add(root);
        //入队便添加
        res.append(root.val).append("!");
        while (! queue.isEmpty()) {
            TreeNode popNode = queue.pop();
            if (popNode.left != null) {
                //入队便添加
                queue.add(popNode.left);
                res.append(popNode.left.val).append("!");
            }else {
                //注意,某一非空节点的左孩子或者右孩子为空也要添加进序列串中,但是该空结点不进队列(同层次遍历)
                res.append("#!");
            }
            if (popNode.right != null) {
                //入队便添加
                queue.add(popNode.right);
                res.append(popNode.right.val).append("!");
            }else {
                //注意
                res.append("#!");
            }
        }
        return res.toString();
    }
    //层次遍历反序列化
    TreeNode Deserialize(String str) {
        String[] nodeValues = str.split("!");
        int i = 0;
        TreeNode root = generateNodeByString(nodeValues[i++]);
        if (root == null) {
            return null;
        }
        //用nodeList来存储尚未连接左右孩子的节点,当出队时,才连接左右孩子,并同时将左右孩子节点(非空)入队
        LinkedList<TreeNode> nodeList = new LinkedList<>();
        nodeList.add(root);
        while(i < nodeValues.length) {
            //出队
            TreeNode curNode = nodeList.poll();
            //连接左孩子,若左孩子非空,则将左孩子入队
            TreeNode leftNode = generateNodeByString(nodeValues[i++]);
            curNode.left = leftNode;
            if (leftNode != null) {
                nodeList.add(leftNode);
            }
            //连接右孩子,若右孩子非空,则将右孩子入队
            TreeNode rightNode = generateNodeByString(nodeValues[i++]);
            curNode.right = rightNode;
            if(rightNode != null) {
                nodeList.add(rightNode);
            }
        }
        return root;
    }

    //根据传入的字符串,返回空结点或者其他节点
    TreeNode generateNodeByString(String value) {
        if("#".equals(value)) {
            return null;
        }else {
            return new TreeNode(Integer.valueOf(value));
        }
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值