二叉树:使用后序遍历算法实现二叉树的序列化和反序列化(Java)

看LeetCode的第297道题目,给出一个二叉树的根节点,要求你把它序列化为一个字符串,然后把这个字符串反序列化为原来二叉树。

我们拿出一个最简单的二叉树,假设我们使用后序遍历递归,就是左子树-右子树-根节点,那么我们需要遍历根节点的左子树,左子树的节点拿到,读取它的值,将它append到开始建立的一个StringBuilder字符串中。然后我们再遍历右子树,拿到它的值,把它append到StringBuilder字符串中。然后遍历根节点,把它的值append到StringBuilder中。如果在递归的过程中,其中某个根节点的某个左右子树为null,那么我们也要将它append到StringBuilder中,符号位“#”。在StringBuilder中,每个节点的值需要用逗号“,”隔开。

因此我们可以得到下面的serialize()函数:

public class Solution{ 
    String SEP = ",";
    String NULL = "#";
    public String serialize(TreeNode root) { 
        StringBuilder sb = new StringBuilder();
        serialize(root, sb);
        return sb;
    
    }

    public void serialize(TreeNode root, StringBuilder sb) { 
        //这里有一个问题,到底先append分隔符SEP还是空值NULL
        //如果root为null,先append分隔符SEP,为“,#”,否则为“#,”。不管怎么样,貌似都没问题,但是我觉得第一种更保险一些;这里
        //假设是二叉树[1,2,3],先append分隔符SEP,结果为“,#,#,2,#,#,3,1”,否则为"#,#,2,#,#,3,1"
        if(root == null) { 
            sb.append(NULL).append(SEP);
            return;
        }
        
        serialize(root.left, sb);
        serialize(root.right, sb);
        
        //后序遍历位置
        sb.append(root.val).append(SEP);
    }
}

然后需要对上面序列化的二叉树进行解序列化。如何把一个字符串还原成一个二叉树呢?

正常来说,要想从一个后序遍历字符串还原二叉树还需要中序遍历字符串,可是刚刚我们在序列化的时候对空节点也进行了存储。首先,我们需要将字符串按照逗号分隔开,存进一个List。

怎么分隔开,这里我们使用String的split()函数。好,注意,那么刚刚我们的疑问就解决了。StringBuilder字符串先append空节点NULL,然后append分隔符SEP。为什么呢?因为对于“,#”,对它使用split()函数后分为”” 和 “#”,而对于“#,”对它使用split()函数后只有一个”#”。所以当我们以后从List拿出这个空字符串””的时候,不就要多处理一下吗?

要从List构造二叉树,首先要构造节点。一般来说我们需要构造三个节点,根节点,左节点和右节点,分别我root,left,right。构造节点,需要先构造根节点,才能构造左右节点。按照这个顺序,要从List中构造节点,只能从List末尾构造起,因为它的根节点的值放在后面,然后是右节点,然后是左节点。我们把这个构造节点的动作不断递归,就可以自顶向下构造出一个二叉树啦。

但是,要从List的末尾构造节点,我们就需要把List翻转吗?其实Java里面有一个LinkedList,我们使用它的removeLast(),就可以从List的末尾开始构造二叉树。

因此我们的deserialize()函数如下:

public TreeNode deserialize(String data) { 
	LinkedList<String> list = new LinkedList<>();
	for(s : data.split(SEP)) { 
		list.addLast(s);
	}
	return deserialize(list);
}

public TreeNode deserialize(LinkedList<String> list) { 
	if(list.isEmpty()) { 
        return null;
    }
    
    String s = list.removeLast();
    if(s.equals(NULL)) { 
        return null;
    }
    TreeNode root = new TreeNode(Integer.parseInt(s));
    
    root.right = deserialize(list);
    root.left = deserialize(list);
    
    return root;
}
    原文作者:qq_43416596
    原文地址: https://blog.csdn.net/qq_43416596/article/details/115051439
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞