二叉树——序列化、反序列化

1. 二叉树的序列化、反序列化

1.1. 问题

将一个二叉树序列化为字符串。

从序列化后的字符串重建一棵二叉树。

1.2. 思路

#表示空节点,用!表示一个节点的结尾。

这道题可以用二叉树的前序遍历、后序遍历、层序遍历来做。

中序遍历不好做,因为给定一个序列后,没办法一下子将根节点找出来。

对于前序、后序遍历,可以考虑递归和使用栈的方法来弄,使用morris遍历不好做。因为序列化后的字符串需要包含空节点的信息,而morris遍历,不好来拿空节点的信息。

1.3. 代码

1.3.1. 前序法

    public static String serializeByPre(TreeNode<Integer> root) {
        StringBuilder builder = new StringBuilder();
        buildPreStr(root, builder);
        return builder.toString();
    }

    private static void buildPreStr(TreeNode<Integer> node, StringBuilder builder) {
        if (node == null) {
            builder.append("#!");
            return;
        }

        builder.append(node.val).append("!");
        buildPreStr(node.left, builder);
        buildPreStr(node.right, builder);
    }

    public static TreeNode<Integer> deserializeByPre(String str) {
        String[] strs = str.split("!");
        Queue<String> queue = new LinkedList<>(Arrays.asList(strs));
        return buildTreeByPre(queue);
    }

    private static TreeNode<Integer> buildTreeByPre(Queue<String> queue) {
        String str = queue.remove();
        if ("#".equals(str)) {
            return null;
        }
        TreeNode<Integer> node = new TreeNode<>(Integer.valueOf(str));
        node.left = buildTreeByPre(queue);
        node.right = buildTreeByPre(queue);
        return node;
    }

1.3.2. 后序法

    public static String serializeByPost(TreeNode<Integer> root) {
        if (root == null) {
            return "#!";
        }
        StringBuilder builder = new StringBuilder();
        buildPostStr(root, builder);
        return builder.toString();
    }

    private static void buildPostStr(TreeNode<Integer> head, StringBuilder builder) {
        if (head == null) {
            builder.append("#!");
            return;
        }
        buildPostStr(head.left, builder);
        buildPostStr(head.right, builder);
        builder.append(head.val);
        builder.append('!');
    }

    public static TreeNode<Integer> deserializeByPost(String postStr) {
        String[] nodes = postStr.split("!");
        Stack<String> stack = new Stack<>();
        for (String s :nodes) {
            stack.push(s);
        }
        return buildTreeByPost(stack);
    }

    public static TreeNode<Integer> buildTreeByPost(Stack<String> stack) {
        String s = stack.pop();
        if(s.equals("#")) {
            return null;
        }
        TreeNode<Integer> head = new TreeNode<>(Integer.valueOf(s));
        head.right = buildTreeByPost(stack);
        head.left = buildTreeByPost(stack);
        return head;
    }

1.3.3. 层序法

    public static String serializeByLevel(TreeNode<Integer> root) {
        if (root == null) {
            return "#!";
        }

        StringBuilder builder = new StringBuilder();
        Queue<TreeNode<Integer>> queue = new LinkedList<>();
        queue.add(root);
        TreeNode<Integer> nil = new TreeNode<>();
        while (!queue.isEmpty()) {
            TreeNode<Integer> node = queue.remove();
            if (node == nil) {
                builder.append("#");
            } else {
                builder.append(node.val);
                queue.add(node.left == null ? nil : node.left);
                queue.add(node.right == null ? nil : node.right);
            }
            builder.append("!");
        }
        return builder.toString();
    }

    public static TreeNode<Integer> deserializeByLevel(String data) {
        if (data == null || data.isEmpty() || "#!".equals(data)) {
            return null;
        }

        Queue<String> children = new LinkedList<>(Arrays.asList(data.split("!")));
        Queue<TreeNode<Integer>> parents = new LinkedList<>();

        TreeNode<Integer> root = new TreeNode<>(Integer.valueOf(children.remove()))
        parents.add(root);
        while (!parents.isEmpty()) {
            TreeNode<Integer> node = parents.remove();
            String leftVal = children.remove();
            String rightVal = children.remove();

            if ("#".equals(leftVal)) {
                node.left = null;
            } else {
                TreeNode<Integer> left = new TreeNode<>(Integer.valueOf(leftVal));
                node.left = left;
                parents.add(left);
            }

            if ("#".equals(rightVal)) {
                node.right = null;
            } else {
                TreeNode<Integer> right = new TreeNode<>(Integer.valueOf(rightVal));
                node.right = right;
                parents.add(right);
            }
        }
        return root;
    }
posted @ 2022-05-11 18:52  迈吉  阅读(36)  评论(0)    收藏  举报