二叉树序列化
将序列化的数据存储到一个数组里,要求数据后面加”!“,没有的数据的用”#!“表示。
#include<iostream>
#include<string>
using namespace std;
typedef struct Node
{
char data;
struct Node *lchild, *rchild;
}*BiTree, BiTNode;
void CreatBiTress(BiTree &T);
string PerOrderTraverse(BiTree T);
string buf;
int main()
{
BiTree T;
string buff;
cout << "输入内容创建二叉树" << endl; //AB#CD##E##F#GH###
CreatBiTress(T);
buff = PerOrderTraverse(T);
cout << buff << endl;
return 0;
}
//创建二叉树
void CreatBiTress(BiTree &T)
{
char ch;
cin >> ch;
if (ch == '#') T = NULL;
else{
T = new BiTNode;
T->data = ch;
CreatBiTress(T->lchild);
CreatBiTress(T->rchild);
}
}
//先序遍历
string PerOrderTraverse(BiTree T)
{
if (T)
{
buf = buf + T->data + "!";
PerOrderTraverse(T->lchild);
PerOrderTraverse(T->rchild);
}
else buf = buf + "#!";
return buf;
} 这里的buf为全局变量,最后的数据也被存储在buff中。
运行结果展示:

二叉树的反序列化:
对于上面的通过先序二叉树遍历的方法得到的序列化,我们也必须通过先序遍历来反序列化之前的数据。
但是值得注意的是,对于原始的数组buff的值,我们需要先进行处理,将数据分隔出来。
size_t pos = buff.find('!');
while (pos<buff.length()&&pos>0)
{
buff.erase(pos, 1);
pos = buff.find('!');
}
cout << buff << endl;由于”!“的长度为1,因此只要知道每个”!”的定位变可以通过erase进行删除,上面通过一个循环判断一直新招“!”的定位,当字符串中含有“!”时,返回的值便是0到字符串长度之间,否则肯定不在这个范围内,于是便跳出循环。
注意一开始的创建二叉树的过程,其实就是将输入流里的进行反系列化,因此为了达到同样的效果,我们需要对字符串进行处理。那么第一件事就是一直去字符串的第一个数值:buf.front(),对于第一个字符取了之后便进行判断,然后建造二叉树的节点,处理完第一个数值,为了效仿输入流的效果,我们应该将这个数值从字符串中移除:buf=buf.substr(1)。这里便是更新字符串buf是的字符串的第一位移除。因此构建反序列的函数便可以效仿者写出来:
void CreatBiTress2(BiTree &T)
{
if (buf.front() == '#')
{
buf = buf.substr(1);
T = NULL;
}
else{
T = new BiTNode;
T->data = buf.front();
buf = buf.substr(1);
CreatBiTress2(T->lchild);
CreatBiTress2(T->rchild);
}
}我们可以发现和一开始的构建二叉树的程序几乎没有区别。
主函数演示:
int main()
{
int t = 0;
BiTree T,T2;
string buff;
cout << "输入内容创建二叉树" << endl; //AB#CD##E##F#GH###
CreatBiTress(T);
buff = PerOrderTraverse2(T);//序列化二叉树
cout << buff << endl;
cout << "////////////////" << endl;
size_t pos = buff.find('!');
while (pos<buff.length()&&pos>0)
{
buff.erase(pos, 1);
pos = buff.find('!');
}
cout << buff << endl; //处理buff字符串,并删除“!”
buf = buff; //将buff复制到buf
cout <<"buf: "<< buf << endl;
CreatBiTress2(T2); //反序列化buf
PerOrderTraverse(T2); //打印二叉树
return 0;
}运行结果:

本文介绍了如何使用先序遍历对二叉树进行序列化和反序列化。在序列化过程中,数据后跟'!',空节点用'#!'表示。反序列化时,通过先序遍历的方式,根据'!'的位置处理数组,构建二叉树节点,并从字符串中移除已处理的数值。
&spm=1001.2101.3001.5002&articleId=80421267&d=1&t=3&u=5319e6422004419b8b79de9790bbc8ac)
6万+

被折叠的 条评论
为什么被折叠?



