二叉树的序列化与反序列化[前序遍历+回溯]

253 阅读1分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第18天,二叉树的序列化与反序列化[前序遍历+回溯] - 掘金 (juejin.cn)

前言

对于树的序列化和反序列化,用什么遍历序列化,就用什么遍历把其还原出来,本文记录前序遍历序列化,采用回溯+模拟树左右递归来生成树。

一、二叉树的序列化与反序列化

image.png

二、前序遍历 & 回溯生成树

package everyday.hard;

public class Codec {
    // 先遍历形成字符串,再遍历字符串回溯生成树。
    // Encodes a tree to a single string.
    public String serialize(TreeNode root) {
        preOrder(root);
        return sb.deleteCharAt(sb.length() - 1).toString();
    }

    StringBuilder sb = new StringBuilder();

    private void preOrder(TreeNode root) {
        if (root == null) {
            sb.append("#,");
            return;
        }
        int len = sb.length();
        sb.append(root.val).append(',');

        preOrder(root.left);
        preOrder(root.right);
    }

    // Decodes your encoded data to tree.
    public TreeNode deserialize(String data) {
        String[] strs = data.split(",");

        return buildTree(strs);
    }

    private TreeNode buildTree(String[] strs) {
        if (idx == strs.length) return null;
        if ("#".equals(strs[idx])) {
            ++idx;
            return null;
        }
        // bug1:有负数的情况就乱了!
        TreeNode root = new TreeNode(Integer.parseInt(strs[idx++]));
        // 模拟左右孩子递归。
        root.left = buildTree(strs);
        root.right = buildTree(strs);

        return root;
    }

    int idx;

    // Definition for a binary tree node.
    public class TreeNode {
        int val;
        TreeNode left;
        TreeNode right;

        TreeNode(int x) {
            val = x;
        }
    }
}

总结

1)树的遍历 & 如何生成树,本质都是从子树构建处更大的子树,前序遍历如果有null的记录,则不断遍历值的来回溯生成;另一种就是典型的中序遍历 + 前序/后序,主要就算不断的分区间,直到一个区间只有一个节点 || 没有节点,分别表示叶子节点和空节点。

2)树问题,可归类为前序遍历 & dfs,中序遍历 & 平衡二叉,后序遍历 & 回溯,层序遍历 & bfs.

参考文献

[1] LeetCode 二叉树的序列化与反序列化