Serialize and Deserialize Binary Tree

题目来源 leetcode 297

给定一棵二叉树,二叉树的每个结点的信息为一个整数,要求实现两个功能(1)将二叉树转换为一个字符串。(2)将字符串转换为一棵二叉树。二叉树和字符串之间具体如何转换不做具体规定,只需要满足将一棵二叉树T利用功能(1)转换为一个字符串S后,再利用功能(2)可以将S转换为T。

因为要将结点具有整数信息的二叉树转换为字符串,则需要用字符串表示数字,并且可以区分哪些字符构成一个数字。字符串采用以下格式:\t数字1\t数字2\t数字3......。每一个代表数字的子字符串之前有一个制表符。字符串中的数字的顺序为对二叉树进行BFS,依次获取的结点数值的顺序,若某个结点的子结点不到两个,则对于空的子结点,字符串中对应的子字符串为空字符串。这样,在字符串中每一个数字都代表一个非空结点,并且这些结点在字符串中都可以找到两个数字或者空字符串代表其子结点。比如在一个根结点为10,根结点的左右子结点分别为20和30的二叉树中,字符串为\t10\t20\t30\t\t\t\t(最后4个制表符代表了4个空子结点)。

要将字符串恢复为二叉树,也可以采用类似BFS的做法。设置一个队列,读取第一个数字,代表根结点,进入队列。之后进入一个循环,每次循环向后读取字符串中的两个数字(可能为空,第一次循环时已经读取过第一个数字),这两个数字就代表了队头的左右子结点,循环结束队头出队,当字符串被读取完毕之后,字符串到二叉树的转换完毕。

struct TreeNode {
	int val;
	TreeNode *left;
	TreeNode *right;
	TreeNode(int x) : val(x), left(NULL), right(NULL) {}
};
string itoa(int num)//数字变为字符串
{
	string ans;
	bool neg = 0;
	if (num < 0)
	{
		num = -num;
		neg = 1;
	}
	if (num == 0)
		return "0";
	while (num)
	{
		ans += (num % 10 + '0');
		num = num / 10;;
	}
	for (int i = 0; i < ans.size()/2; i++)
	{
		char ch = ans[ans.size() - 1 - i];
		ans[ans.size() - i - 1] = ans[i];
		ans[i] = ch;
	}
	if (neg)
		ans = "-" + ans;
	return ans;
}
int atoi(string s)//字符串变为数字
{
	int num = 0;
	int index = 0;
	bool neg = 0;
	if (s[0] == '-')
	{
		index = 1;
		neg = 1;
	}
	for (int i = index; i < s.size(); i++)
	{
		num = num * 10 + s[i] - '0';
	}
	if (neg)
		num = -num;
	return num;
}
string getstring(string s, int index)//获取大字符串中的一个数字
{
	string ans;
	for (int i = index + 1; i < s.size() && s[i] != '\t'; i++)
	{
		ans += s[i];
	}
	return ans;
}
string serialize(TreeNode* root) {
	string s;
	if (!root)
		return s;
	queue<TreeNode*> q;
	q.push(root);
	s += '\t';
	s += (itoa(root->val));
	while (!q.empty())
	{
		TreeNode* temp = q.front();
		bool left = 0;
		bool right = 0;
		if (temp->left)
		{
			q.push(temp->left);
			s += '\t';
			s += (itoa(temp->left->val));
			left = 1;
		}
		if (!left)
			s += '\t';
		if (temp->right)
		{
			q.push(temp->right);
			s += '\t';
			s += (itoa(temp->right->val));
			right = 1;
		}
		if (!right)
			s += '\t';
		q.pop();
	}
	return s;
}


TreeNode* deserialize(string data) {
	if (data.size() == 0)
		return NULL;
	TreeNode* root = new TreeNode(atoi(getstring(data,0)));
	queue<TreeNode*> q;
	int index = 0;
	q.push(root);
	index += getstring(data, index).size() + 1;
	while (!q.empty())
	{
		TreeNode* temp = q.front();
		int size = getstring(data, index).size();
		if (size!= 0)//空子结点
		{
			string s = getstring(data, index);
			temp->left = new TreeNode(atoi(s));
			q.push(temp->left);
			index += size + 1;
			size = getstring(data, index).size();
		}
		else
		{
			index++;
			size = getstring(data, index).size();
		}
		if (index >= data.size())
			break;
		if (size != 0)
		{
			string s = getstring(data, index);
			temp->right = new TreeNode(atoi(s));
			q.push(temp->right);
			index += size + 1;
			size = s.size();
			
		}
		else
		{
			index++;
		}
		if (index >= data.size())
			break;
		q.pop();
	}
	return root;
}




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值