1.什么叫二叉树的序列化和反序列化
我们在内存中建立起了一颗二叉树,当电脑关机后,内存中的东西又消失了,我们还得自己手工去建立。
①把内存中的二叉树存储到文件或其他介质中的过程我们叫序列化
②反序列化就是例如根据文件中的字符串的内容,把这个二叉树又重新构造起来。
2.二叉树的结构
struct NODE
{
struct NODE *Left;
struct NODE *Right;
int Value;
NODE(int v):Left(NULL), Right(NULL), Value(v){
}
};
我们要将这么一颗二叉树序列化和反序列化(用先序 别的序列同理)
3.序列化
我们将一颗二叉树转化成字符串的形式
首先我们介绍二叉树先序序列化的方式,假设序列化的结果字符串为str,
初始时str等于空字符串。先序遍历二叉树,如果遇到空节点,就在str的末尾加上
“#_”,“#”表示这个节点为空,节点值不存在,当然你也可以用其他的特殊字符,
“_”表示一个值的结束。如果遇到不为空的节点,假设节点值为3,
就在str的末尾加上“3_”
那么上面那个二叉树就可表示为
"1_2_4_#_#_5_#_#_3_6_#_#_7_#_#_"
string MyItoA(int nNum)//将value转化为string
{
string res;
while(nNum)
{
res += (nNum%10)+'0';
nNum /= 10;
}
reverse(res.begin(), res.end());
return res;
}
void seralize(string &Str, NODE *Head)//给一个头结点 获取一个字符串
{
if(NULL == Head)//空节点
{
Str += "#_";
return;
}
Str += MyItoA(Head->Value);//"value_"的形式
Str += "_";
seralize(Str, Head->Left);//递归左和右
seralize(Str, Head->Right);
}
4.反序列化
所谓反序列化是根据一个字符串重新建立一棵二叉树,反序列化是序列化的逆过程,对于一个字符串,首先按照分隔符_将其分割为字符串数组,每个字符串元素代表一个结点,然后开始重建二叉树。由于每个结点再字符串中只保留了一个val值,因此需要根据结点的值val重新构建Node结点对象,并且为这个结点对象的left和right进行赋值
//对字符串进行分割 然后存放到一个队列当中
void split (const string &Str, queue<string> & Queue)
{
int i, j;
string Temp;
for(i = 0; '\0' != Str[i]; i++)
{
if('_' == Str[i])
{
Queue.push(Temp);
Temp = "";
continue;
}
Temp+=Str[i];
}
}
//根据分割得到的队列 来重建树
NODE * ReconPreOrder(queue<string> & Queue)
{
string Temp = Queue.front();
Queue.pop();
if('#' == Temp[0])//空节点
{
return NULL;
}
int Value = 0;
for(int i = 0; '\0' != Temp[i]; i++)//获取value
{
Value = Value*10+ Temp[i]-'0';
}
NODE *New = new NODE(Value);//创建根
New->Left = ReconPreOrder(Queue);//创建左右子树
New->Right = ReconPreOrder(Queue);
return New;
}
5.运行
//先序遍历
void PreOrder(NODE *Head)
{
if(NULL == Head)
return;
cout<<Head->Value<<" ";
PreOrder(Head->Left);
PreOrder(Head->Right);
}
int main(int argc, char** argv)
{
string Str = "1_2_4_#_#_5_#_#_3_6_#_#_7_#_#_";
queue<string> Queue;
split (Str, Queue);//划分
NODE *Head = ReconPreOrder(Queue);//重建树
PreOrder(Head);//先序遍历
cout<<endl;
string empty = "";
seralize(empty, Head);//根据重建后的树 序列化
cout<<empty<<endl;
if(Str == empty)//比较两个字符串
{
cout<<"Equal"<<endl;
}
return 0;
}