二叉树的序列化与反序列化

一个二叉树被序列化为数组,如何反序列化,也就是如何从序列化好的一个数组恢复成二叉树?

在上一篇文章中讲述了如何将一个有序数组创建成一个二叉搜索树,那么如果将将一个儿茶搜索树序列化为一个有序数组,然后按照上面的方法在反序列化即可。对二叉搜索树进行中序遍历即可得到一个有序的数组,那么上篇文章已经完成了对二叉搜索树的序列化和反序列化。同时如果想将二叉搜索树的序列化和反序列化的结果通过文件读取,也是同样的道理。

设计一个算法,将一棵二叉搜索树(Binary Search Tree,BST)保存到文件中,需要能够从文件中恢复原来的二叉搜索树。注意算法的时空复杂度。

如果通过文件的话,我们使用中序遍历是不合适的,因为从文件读取时顺序读取的。但是先序遍历存放到文件,然后从文件中按照依序读取,是符合要求的。

void DeSerialize(int min,int max,int& val,BinTree*& root,ifstream& fin)
{
     int temp;
     if(val > min && val < max)
     {
          temp = val;
          root = new BinTree;
          root->right = NULL;
          root->left = NULL;
          root->value = temp;
          if(fin>>val)
          {
         DeSerialize(min,temp,val,root->left,fin);
         DeSerialize(temp,max,val,root->right,fin);             

     }
       }

     }
void DeSerialize(BinTree*& root)
{
     ifstream fin("data.txt");
     int val;
     fin>>val;
     DeSerialize(-1000,20000,val,root,fin);
     fin.close();
}

上面是对二叉搜索树的序列和反序列化的方法

因为二叉树与二叉搜索树的性质不同,所以不能简单的采用前面文章中的方法。不过,我们可以采用先序遍历的思想,只是在这里需要改动。为了能够在重构二叉树时结点能够插入到正确的位置,在使用先序遍历保存二叉树到文件中的时候需要把NULL结点也保存起来(可以使用特殊符号如“#”来标识NULL结点)。

假定二叉树如下所示:

    _30_
   /    \   
  10    20
 /     /  \
50    45  35

则使用先序遍历,保存到文件中的内容如下:

30 10 50 # # # 20 45 # # 35 # #

序列化二叉树

先序遍历的代码可以完成序列化二叉树的工作,不管你信不信,反正我是信了。代码如下:

void SerializeBinaryTree(BinTree *p, ostream &out)  //BinaryTree是二叉树结构体,typedef struct node BinaryTree.
    {
      if (!p) {
        out << "# ";
      } else {
        out << p->data << " ";
        SerializeBinaryTree(p->left, out);
        SerializeBinaryTree(p->right, out);
      }
    }  

反序列化二叉树

从文件中读取二叉树结点并重构的方法与前面相似。采用先序遍历的思想每次读取一个结点,如果读取到NULL结点的标识符号“#”,则忽略它。如果读取到结点数值,则插入到当前结点,然后遍历左孩子和右孩子。

void readBinaryTree(BinTree *&p, ifstream &fin)
    {
      int token;
      bool isNumber;
      if (!readNextToken(token, fin, isNumber)) //readNextToken读取文件下一个值,如果是数字返回true,否则返回false
        return;
      if (isNumber) {
        p = new BinTree;
        p->value = toekn;         //newNode函数创建新结点,设定data为token,left和right初始化为NULL
        p->left = NULL;
        p->right = NULL;
        readBinaryTree(p->left, fin);
        readBinaryTree(p->right, fin);
      }
    }  
时间: 2024-12-14 18:45:04

二叉树的序列化与反序列化的相关文章

lintcode 中等题:binary tree serialization 二叉树的序列化和反序列化

题目 二叉树的序列化和反序列化 设计一个算法,并编写代码来序列化和反序列化二叉树.将树写入一个文件被称为“序列化”,读取文件后重建同样的二叉树被称为“反序列化”. 如何反序列化或序列化二叉树是没有限制的,你只需要确保可以将二叉树序列化为一个字符串,并且可以将字符串反序列化为原来的树结构. 样例 给出一个测试数据样例, 二叉树{3,9,20,#,#,15,7},表示如下的树结构: 3 / 9 20 / 15 7 我们的数据是进行BFS遍历得到的.当你测试结果wrong answer时,你可以作为输

Leetcode 297.二叉树的序列化和反序列化

二叉树地序列化和反序列化 序列化是将一个数据结构或者对象转换为连续的比特位的操作,进而可以将转换后的数据存储在一个文件或者内存中,同时也可以通过网络传输到另一个计算机环境,采取相反方式重构得到原数据. 请设计一个算法来实现二叉树的序列化与反序列化.这里不限定你的序列 / 反序列化算法执行逻辑,你只需要保证一个二叉树可以被序列化为一个字符串并且将这个字符串反序列化为原始的树结构. 示例:  你可以将以下二叉树: 序列化为 "[1,2,3,null,null,4,5]" 提示: 这与 Le

二叉树的序列化和反序列化(先序,按层序列化),包含递归图

目录 二叉树的序列化与反序列化 按层序列化 使用#!和!的原因: 二叉树的序列化与反序列化 序列化:将对象的状态信息转换为可以存储或传输的形式的过程 二叉树的序列化:就是将二叉树转换成字符串 二叉树的反序列化:通过字符串还原一棵二叉树,返回树的头节点. 先序序列化二叉树 上面这棵树的先序序列化结果为5!3!2!1!#!#!#!4!#!#!8!7!6!#!#!#!10!9!#!#!11!#!#! 从上图中我们可以看出在节点为空的位置使用"#!"来代替,每个节点后的数值都添加一个"

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

http://blog.csdn.net/qq_27703417/article/details/70958692 先序遍历二叉树,如果遇到空节点,就在str的末尾加上"#!","#"表示这个节点为空,节点值不存在,当然你也可以用其他的特殊字符,"!"表示一个值的结束.如果遇到不为空的节点,假设节点值为3,就在str的末尾加上"3!".现在请你实现树的先序序列化. 先序遍历 import java.util.*; //使用递归

二叉树的序列化、反序列化

一. 使用先序遍历的方式 [1]中的方式是采用设定#的方式,当访问读取了#时候,创建null,返回. 二.二叉搜索树的序列化 二叉搜索树具有的有序的性质,可以利用这个性质来递归的反序列化BST 对当前节点要处理的数据的范围设定一个边界,当读取的值是在这个范围里面的时候,则进行node的创建,否则创建NULL节点,对于值的node创建需要递归到上一层递归,寻找新的方案,如果还是不行,以此类推. [1] http://blog.csdn.net/pi9nc/article/details/97016

树(7)-----二叉树的序列化和反序列化

1.序列化:层次遍历[用字符串来存储] 2.反序列化:用队列存已经建立的节点,从序列化后的字符串列表取数来建立树 def serialize(self, root): """Encodes a tree to a single string. :type root: TreeNode :rtype: str """ if not root: return "" prev,strres=[root],"" w

leetcode 297二叉树的序列化与反序列化

采用层序遍历的顺序,储存每一层的值,不存在的或者NULL值用#代替,每个位置以'/'结束 /** * Definition for a binary tree node. * struct TreeNode { * int val; * TreeNode *left; * TreeNode *right; * TreeNode(int x) : val(x), left(NULL), right(NULL) {} * }; */ class Codec { public: // Encodes

Leetcode 297. 二叉树的序列化与反序列化

/** * Definition for a binary tree node. * struct TreeNode { * int val; * TreeNode *left; * TreeNode *right; * TreeNode(int x) : val(x), left(NULL), right(NULL) {} * }; */ #include <stringstream> class Codec { public: void serialize(TreeNode* root,

序列化与反序列化二叉树

2018-06-16 18:53:36 序列化 (Serialization)将对象的状态信息转换为可以存储或传输的形式的过程.反序列化顾名思义就是通过信息流对对象进行重建的过程. 一般来说序列化和反序列化有如下的作用: 1.以某种存储形式使自定义对象持久化: 2.将对象从一个地方传递到另一个地方. 3.使程序更具维护性. 本篇文章主要讨论的是二叉树的序列化和反序列化,分别讨论了普通二叉树和二叉搜索树的情况. 一.普通二叉树的序列化和反序列化 问题描述: 问题求解: 序列化和反序列化二叉树本质上