算法 - 序列化二叉树

题目

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

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

二叉树的反序列化是指:根据某种遍历顺序得到的序列化字符串结果str,重构二叉树。

例如,我们可以把一个只有根节点为1的二叉树序列化为"1,",然后通过自己的函数来解析回这个二叉树

思考

这道题考验的是二叉树的遍历!参考了别人的解法,有使用层次遍历解法也有前序遍历解法。
但是我了下逻辑都挺麻烦,便想找个相对逻辑简单的解法。
我想到了 “二叉堆”,二叉堆是二叉树的数组形式。
序列化 -> 思路就是将二叉树通过 堆 这一个中介 转换为字符串。
反序列化 -> 将字符串转换为堆,然后将堆转换为二叉树。

虽然看似中间多了一层转换,感觉麻烦了些,但是看下代码就知道,其实是比其他解法简单了。因为我这里也算是将复杂问题进行拆解,别人都是一步到位,但是这一步太麻烦,而我是分两步走,然而两步都非常简单,你选哪个?

上码


    // 序列化
    static String Serialize(TreeNode root) {
        Object[] array = new Object[50];
        serRecursive(array, 1, root);
        StringBuilder builder = new StringBuilder();
        for (Object s : array) {
            if (s == null) {
                builder.append("#").append(",");
            } else {
                builder.append(s).append(",");
            }
        }
        return builder.toString();
    }

    // 递归将二叉树对应到数组堆
    private static void serRecursive(Object[] array, Integer nodeIdx, TreeNode node) {
        if (node == null) {
            return;
        }
        array[nodeIdx - 1] = node.val;
        serRecursive(array, nodeIdx * 2, node.left);
        serRecursive(array, nodeIdx * 2 + 1, node.right);
    }

    // 反序列化
    static TreeNode Deserialize(String str) {
        List<String> list = Arrays.asList(str.split(","));
        String r0 = list.get(0);
        if ("#".equals(r0)) {
            return null;
        }

        TreeNode root = new TreeNode(Integer.parseInt(r0));
        desRecursive(list, 1, root);
        return root;
    }

    // 递归将数组堆还原成二叉树
    private static void desRecursive(List<String> list, Integer nodeIdx, TreeNode node) {
        int l = nodeIdx * 2;
        int r = nodeIdx * 2 + 1;
        int size = list.size();

        if ((l - 1) < size && !"#".equals(list.get(l - 1))) {
            TreeNode lnode = new TreeNode(Integer.parseInt(list.get(l - 1)));
            node.left = lnode;
            desRecursive(list, l, lnode);
        }

        if ((r - 1) < size && !"#".equals(list.get(r - 1))) {
            TreeNode lnode = new TreeNode(Integer.parseInt(list.get(r - 1)));
            node.right = lnode;
            desRecursive(list, r, lnode);
        }
    }

posted @ 2020-06-10 19:05  慢慢行  阅读(19)  评论(0编辑  收藏  举报