二叉树序列化和反序列化(先序)

本文介绍了如何使用先序遍历对二叉树进行序列化和反序列化。在序列化过程中,数据后跟'!',空节点用'#!'表示。反序列化时,通过先序遍历的方式,根据'!'的位置处理数组,构建二叉树节点,并从字符串中移除已处理的数值。

二叉树序列化

将序列化的数据存储到一个数组里,要求数据后面加”!“,没有的数据的用”#!“表示。

#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;
}

运行结果:


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值