[二叉树]二叉树的序列化和反序列化

题目:二叉树被记录成文章的过程叫做二叉树的序列化,通过文件的内容重建原来的二叉树的过程叫做二叉树的反序列化。给定一颗二叉树的头节点head,并已知二叉树的节点值的类型为32位整型。请设计一种二叉树序列化和反序列化的方案,并用代码实现。

解答:通过先序遍历实现序列化和反序列化

先介绍先序遍历下的序列化过程,首先假设序列化的结果字符串为str,初始化str="".先遍历二叉树,如果遍历到null节点,就在str的末尾加上“#!”,“#表示这个节点为空”,节点值不存在,“!”表示一个值的结束;如果遇到不为空的节点,假设这个值为3,就在str的末尾加上“3!”。比如如图所示的二叉树;

根据上文描述,先序遍历的序列化,最后的结果字符串str为:12!3!#!#!#!.

为什么会在每一个节点的后面都要加上感叹号,如果不加会有歧义,如下图所示,先序遍历str的字符串结果为:123###。所以不加感叹号说明生产的字符串并不代表唯一的树。

先序遍历序列化的全部过程如下:

public class Node{
    public int value;
    public Node left;
    public Node right;
    public Node(int data){
        this.value = data;
    }
}
public String serialByPre(Node head){
    if(haed == null){
        return "#!";
    }
    String res = head.value+"!";
    res += serialByPre(head.left);
    res +=serialByPre(head.right);
   return res;
}

接下来结束如何通过先序遍历序列化的结果字符串str,重构二叉树的过程,即反序列化。

把结果字符串str变成字符串类型的数组,记为values,数组代表一颗二叉树先序遍历的节点顺序。例如str="12!3!#!#!#!",生成的values[12,3,#,#,#],然后用values[0..4]按照先序遍历整棵树。

1.遇到12,生成节点值为12的节点(head),然后用values[1..4]建立节点12的左子树。

2.遇到3,生成节点值为3的节点,它是节点12的左孩子,然后用values[2..4]建立节点3的左子树。

3.遇到#,生成null节点,它是节点3的左孩子,该节点为null,所以这个节点没有后续建立子树的过程。回到节点3后,用values[3..4]建立节点3的右子树。

4.遇到#,生成null节点,它是节点3的右孩子,该节点为null,所以这个节点没有后续建立子树的过程。回到节点3后,再回到节点1,用values[4],建立节点1的右子树。

5.遇到#,生成null节点,它是节点1的右孩子,该节点为null,所以这个节点没有后续建立子树的过程。整个过程结束。

具体代码如下所示:

public Node reconByPreString(String preStr){
    String[] values = preStr.split("!");
    Queue<String>  queue = new LinkedList<String>();
    for(int i=0;i != value.length;i++){
        queue.offer(values[i]);
    }
    return reconPreOrder(queue);
}

public Node reconPreOrder(Queue<String> queue){
    String value = queue.poll();
    if(value.equals("#")){
        reutrn null;
    }
    Node head = new Node(Integer.valueOf(value));
    head.left = reconPreOrder(queue);
    head.right = reconPreOrder(queue);
    reutrn head;

}

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值