我的上一篇有关二叉树的序列化与反序列化传送门: https://blog.csdn.net/pingcoool/article/details/88082739
二叉搜索树
定义:二叉搜索树或者是一棵空树,或者是具有下列性质的二叉树: 若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值; 若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值; 它的左、右子树也分别为二叉排序树。
二叉搜索树的序列化和反序列化(以后序遍历恢复原树为例)
( 以下示例对问题做了一些简化: 假设二叉树的节点值用一个字符表示, 后序遍历的结果中不包含空节点信息 )
我们知道,普通的二叉树是不能由其前中后序遍历结果之一来恢复其原始结构的, 但由于二叉搜索树具有的特殊结构,使得其可以通过前序或后序遍历的结果恢复原树.(与普通二叉树将空节点用”#”的填充的序列化相同,中序遍历的二叉搜索树由于丢失了根节点位置信息,因此仍然不能恢复原树.)
上图中的二叉搜索树后序遍历的结果为:1 3 2 5 6 8 7 4
分析:后序遍历的最后一个元素为二叉树的根节点:
从后向前:
根节点前一个元素(如果大于根)是根节点右子树根;
比根节点值小的第一个元素就是根节点左子树的根;
以上两条就是恢复原树的核心思想.
后序遍历代码 :
public static String postSerializeSearchTree(TreeNode root){
if(root==null){
return "";
}
return postSerializeSearchTree(root.left)+postSerializeSearchTree(root.right)+root.val+"";
}
反序列化 :
public static TreeNode deSerializeSearchTree(char[] chars,int start,int end){//双闭区间
int left=findLeft(chars,start,end);
TreeNode newhead=new TreeNode(Integer.parseInt(chars[end]+""));
if(left>=start){//当前根有左子树
newhead.left=deSerializeSearchTree(chars,start,left);
}
if(left<end-1){//当前根有右子树
newhead.right=deSerializeSearchTree(chars,left+1,end-1);
}
return newhead;
}
附 : 树节点的定义 :
public static class TreeNode {
int val;
TreeNode left = null;
TreeNode right = null;
public TreeNode(int val) {
this.val = val;
}
}