首页 > 技术文章 > 详解序列化二叉树-剑指offer37

maktub-96 2020-12-06 00:11 原文

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

 

 题目分析: 序列化二叉树其实就是一个广度优先遍历(BFS),每一层从左到右遍历即可,此时可以选择使用一个队列,从头节点添加,遍历队列,判断左右节点,不为空则加入队列,此时我们可以使用一个StringBuilder来构建最终的字符串结果:

序列化代码如下:

 1 public String serialize(TreeNode root) {
 2 
 3         // 若头为空则返回一个空序列化结果
 4         if (root == null) {
 5             return "[]";
 6         }
 7             
 8         
 9         // 定义一个队列同于遍历树
10         Queue<TreeNode> queue = new LinkedList<>();
11         queue.add(root);
12 
13         // StringBuilder构建最终字符串
14         StringBuilder string = new StringBuilder();
15 
16         // 字符串首为“[”
17         string.append("[");
18 
19         TreeNode cur;
20 
21         // 遍历队列
22         while(!queue.isEmpty()) {
23 
24             // 出队
25             cur = queue.poll();
26             
27             // 出队为null则将null加入字符串
28             if (cur == null) {
29                 string.append("null");
30                 string.append(",");
31             
32             } else {
33                 queue.add(cur.left);
34                 queue.add(cur.right);
35                 string.append(cur.val);
36                 string.append(",");
37             }
38         }
39 
40         // 将字符串末尾改为“]”
41         string.setCharAt​(string.length()-1,']');
42         
43         
44         return string.toString();
45 
46         
47     }

反序列化其实就是将返回的字符串进行处理,将字符串中的字符串取出变为int类型数字或者null,主要的难点在于将字符串与节点建立联系与字符串的处理,这时同样采取队列的形式,将字符串处理之后,每个元素添加进队列,取出头节点,然后遍历队列中的元素,构建新的节点添加节点即可,如果为空则什么都不做即可(如果不为空寂左到右添加节点即可)

反序列化代码如下:

 1 public TreeNode deserialize(String data) {
 2         // 如果为空则返回null
 3         if (data.equals("[]") || data == null) {
 4             return null;
 5         }
 6         // 将字符串变为字符数组,去掉头尾”[“, “]”
 7         String[] strings = data.substring(1, data.length()-1).split(",");
 8         
 9         // 将头节点构建
10         TreeNode root = new TreeNode(Integer.parseInt(strings[0]));
11         
12         // 使用队列
13         Queue<TreeNode> queue = new LinkedList<>();
14         queue.add(root);
15 
16         int index = 1;
17         while(!queue.isEmpty()) {
18             TreeNode cur = queue.poll();
19             // 字符串不是null ,添加左节点
20             if (!strings[index].equals("null")) {
21                 cur.left = new TreeNode(Integer.parseInt(strings[index]));
22                 queue.add(cur.left);
23                 
24             }
25 
26             // 字符串数组指针后移
27             index++;
28 
29             // 字符串不是null ,添加右节点
30             if (!strings[index].equals("null")) {
31                 cur.right = new TreeNode(Integer.parseInt(strings[index]));
32                 queue.add(cur.right);
33                 
34             }
35 
36             // 字符串数组指针后移
37             index++;
38 
39         }
40 
41 
42         return root;
43         
44     }

整体代码如下

  1 /**
  2  * Definition for a binary tree node.
  3  * public class TreeNode {
  4  *     int val;
  5  *     TreeNode left;
  6  *     TreeNode right;
  7  *     TreeNode(int x) { val = x; }
  8  * }
  9  */
 10 public class Codec {
 11 
 12 
 13 
 14     // Encodes a tree to a single string.
 15     public String serialize(TreeNode root) {
 16 
 17         // 若头为空则返回一个空序列化结果
 18         if (root == null) {
 19             return "[]";
 20         }
 21             
 22         
 23         // 定义一个队列同于遍历树
 24         Queue<TreeNode> queue = new LinkedList<>();
 25         queue.add(root);
 26 
 27         // StringBuilder构建最终字符串
 28         StringBuilder string = new StringBuilder();
 29 
 30         // 字符串首为“[”
 31         string.append("[");
 32 
 33         TreeNode cur;
 34 
 35         // 遍历队列
 36         while(!queue.isEmpty()) {
 37 
 38             // 出队
 39             cur = queue.poll();
 40             
 41             // 出队为null则将null加入字符串
 42             if (cur == null) {
 43                 string.append("null");
 44                 string.append(",");
 45             
 46             } else {
 47                 queue.add(cur.left);
 48                 queue.add(cur.right);
 49                 string.append(cur.val);
 50                 string.append(",");
 51             }
 52         }
 53 
 54         // 将字符串末尾改为“]”
 55         string.setCharAt​(string.length()-1,']');
 56         
 57         
 58         return string.toString();
 59 
 60         
 61     }
 62 
 63     // Decodes your encoded data to tree.
 64     public TreeNode deserialize(String data) {
 65         // 如果为空则返回null
 66         if (data.equals("[]") || data == null) {
 67             return null;
 68         }
 69         // 将字符串变为字符数组,去掉头尾”[“, “]”
 70         String[] strings = data.substring(1, data.length()-1).split(",");
 71         
 72         // 将头节点构建
 73         TreeNode root = new TreeNode(Integer.parseInt(strings[0]));
 74         
 75         // 使用队列
 76         Queue<TreeNode> queue = new LinkedList<>();
 77         queue.add(root);
 78 
 79         int index = 1;
 80         while(!queue.isEmpty()) {
 81             TreeNode cur = queue.poll();
 82             // 字符串不是null ,添加左节点
 83             if (!strings[index].equals("null")) {
 84                 cur.left = new TreeNode(Integer.parseInt(strings[index]));
 85                 queue.add(cur.left);
 86                 
 87             }
 88 
 89             // 字符串数组指针后移
 90             index++;
 91 
 92             // 字符串不是null ,添加右节点
 93             if (!strings[index].equals("null")) {
 94                 cur.right = new TreeNode(Integer.parseInt(strings[index]));
 95                 queue.add(cur.right);
 96                 
 97             }
 98 
 99             // 字符串数组指针后移
100             index++;
101 
102         }
103 
104 
105         return root;
106         
107     }
108 }

 

推荐阅读