剑指offer之面试题37:序列化二叉树

面试题37:序列化二叉树

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

思路:

  1. 因为从前序遍历序列和中序遍历序列中可以恢复出一棵二叉树,所以不难想到把一棵二叉树序列化成一个前序遍历序列和一个中序遍历序列。然后在反序列化时通过这两个序列重构出原二叉树。但是这样做有两个缺点:①该方法要求二叉树中不能有数值重复的节点;②只有当两个序列中所有数据都读出后才能开始反序列化。如果两个遍历序列的数据是从一个流中读出来的,那么可能需要等待较长的时间。
  2. 实际上,如果二叉树的序列化是从根节点开始的,那么相应的反序列化在根节点的数值读出来以后就可以开始了。因此,我们可以根据前序遍历的顺序来序列化二叉树,在碰到 null 值的节点时,这些 null 节点我们用一个特殊的符号来代替,比如说"$"。另外,节点的数值之间要用一个特殊的符号,比如说 “,”。

代码实现:

package Question37;

import com.sun.source.tree.Tree;

import java.io.Serializable;
import java.util.LinkedList;
import java.util.Queue;

public class T01 {

    public static String preSeq = "";

    public static void main(String[] args) {
        TreeNode node1 = new TreeNode(1);
        TreeNode node2 = new TreeNode(2);
        TreeNode node3 = new TreeNode(3);
        TreeNode node4 = new TreeNode(4);
        TreeNode node5 = new TreeNode(5);
        node1.left = node2;
        node1.right = node3;
        node3.left = node4;
        node3.right = node5;

        Serialize(node1);
        System.out.println(preSeq);
        TreeNode root = Deserialize(preSeq);
        System.out.println("123");
    }

    public static String Serialize(TreeNode root) {
        if(root != null) {
            preSeq += "" + root.value + ",";
            Serialize(root.left);
            Serialize(root.right);
        } else {
            preSeq += "$,";
        }
        return preSeq;
    }

    public static TreeNode Deserialize(String data) {
        if(data == null || data.length() == 0) return null;
        Queue<String> queue = new LinkedList<>();
        for(String str : data.split(","))
            queue.offer(str);
        return help(queue);
    }

    public static TreeNode help(Queue<String> queue) {
        if(queue.isEmpty()) return null;
        String str = queue.poll();
        if(!str.equals("$")) {
            int number = Integer.parseInt(str);
            TreeNode root = new TreeNode(number);
            root.left = help(queue);
            root.right = help(queue);
            return root;
        } else {
            return null;
        }
    }
}

class TreeNode {
    int value;
    TreeNode left;
    TreeNode right;

    public TreeNode(int val) {
        this.value = val;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值