二叉树——序列化、反序列化
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; }
作者: 迈吉
出处: https://www.cnblogs.com/stepfortune/
关于作者:迈吉
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出, 原文链接 如有问题, 可邮件(showable@qq.com)咨询.
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 终于写完轮子一部分:tcp代理 了,记录一下
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理