LeetCode-树-层序遍历(BFS)-二叉树的序列化与反序列化

1 二叉树的序列化

        序列化参考:请问 [1, null, 2, 3] 在二叉树测试用例中代表什么 - 力扣(LeetCode) - 支持

        对比“使用前序遍历的一个实现”:LeetCode-树-前序遍历(DFS)-二叉树的序列化与反序列化_hclbeloved的博客-CSDN博客

2 题目

剑指 Offer II 048. 序列化与反序列化二叉树

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

2.1 序列化         

        null的作用就是避免歧义,也就是起到占位符的作用,这样能够明确到底是其父节点的左孩子,还是右孩子。

        当前层如果不是最后一层,最后一个非NULL元素(比如上图中的3)后面的null也要打印出来,因为这样才能标识出来3是其父节点2的左子节点;但是如果当前层是最后一层,最后一个非NULL元素(比如上图中的4)的null则不用打印出来。

        当前层的第一个非NULL元素前面的NULL元素如何处理?

        如果第一个非NULL元素的前面的NULL的父节点是非NULL节点,则这样的NULL元素就需要打印出来,比如2前面的NULL元素的父节点是1,1是一个非NULL节点,所以就需要输出null;

        下一层的元素3,前面 也有NULL节点,但是他们的父节点是NULL节点,此时就不需要输出null。

        判断是否是最后一层的标志就是:该层的子节点全部是NULL节点。

2.2 反序列化

        需要先保存父节点,然后让父节点指向后续的子节点。

2.3 实现

class Codec {
public:

	// Encodes a tree to a single string.
	string serialize(TreeNode* root) {
		string res;
		res.append(1, '[');
		do
		{
			if (!root)
				break;			

			queue<TreeNode*> q;
			q.push(root);

			int lastNonNullIndex = 1, step = 0;
			//lastNonNullIndex为0说明上一层是最后一层
			while (lastNonNullIndex)
			{
				queue<TreeNode*> q2;
				lastNonNullIndex = 0;
				int validLevelSize = 0;
				
				while (!q.empty())
				{
					TreeNode* tmp = q.front();
					q.pop();
					if (step)
					{
						if (tmp)
						{
							res.append(1, ',').append(to_string(tmp->val));
						}
						else
						{
							res.append(1, ',').append("null");
						}
					}
					else
					{
						if (tmp)
						{
							res.append(to_string(tmp->val));
						}
						else
						{
							res.append("null");
						}
					}

                    //非NULL节点的子节点(包含NULL子节点)才能入队
					if (tmp)
					{
						q2.push(tmp->left);
						++validLevelSize;
						if (tmp->left)
							lastNonNullIndex = validLevelSize;

						q2.push(tmp->right);
						++validLevelSize;
						if (tmp->right)
							lastNonNullIndex = validLevelSize;
					}
				}

				++step;
				q.swap(q2);
			}			
		} while (0);

        //删除最后一层的额外的尾部null
		while (res.length() > 4 && res.substr(res.length() - 4) == string("null"))
		{
			res.resize(res.length() - 5);
		}
		res.append(1, ']');
		return res;
	}

	// Decodes your encoded data to tree.
	TreeNode* deserialize(string data) {
		if (data.empty())
			return NULL;

		TreeNode* root = NULL, *tmp = NULL, *parent = NULL;
		size_t pos = -1, lastPos = 1;
		string str;
		queue<TreeNode*> q;
		while ((pos = data.find(',', lastPos)) != string::npos)
		{
			str = data.substr(lastPos, pos - lastPos);
			lastPos = pos + 1;

			if (str.compare("null") == 0)
			{
				tmp = NULL;
			}
			else
			{
				tmp = new TreeNode(std::stoi(str));
			}

			q.push(tmp);
		}

		str = data.substr(lastPos, data.length() - 1 - lastPos);
		if (!str.empty())
		{
			tmp = new TreeNode(std::stoi(str));
			q.push(tmp);
		}

		queue<TreeNode*> q2;
		while (!q.empty())
		{
            tmp = q.front();
            q.pop();
            if (!root)
            {
                root = tmp;
            }

            if (!parent)
            {
                if (!q2.empty())
                {
                    parent = q2.front();
                    q2.pop();
                    parent->left = tmp;
                }
            }
            else
            {
                parent->right = tmp;
                parent = NULL;
            }

            //q2中保存的是用作父节点的节点,null节点不能作为父节点,所以不需要放入q2中
            if (tmp)
            {
                q2.push(tmp);
            }
		}

		return root;
	}
};

2.4

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
LeetCode-Editor是一种在线编码工具,它提供了一个用户友好的界面编写和运行代码。在使用LeetCode-Editor时,有时候会出现乱码的问题。 乱码的原因可能是由于编码格式不兼容或者编码错误导致的。在这种情况下,我们可以尝试以下几种解决方法: 1. 检查文件编码格式:首先,我们可以检查所编辑的文件的编码格式。通常来说,常用的编码格式有UTF-8和ASCII等。我们可以将编码格式更改为正确的格式。在LeetCode-Editor,可以通过界面设置或编辑器设置来更改编码格式。 2. 使用正确的字符集:如果乱码是由于使用了不同的字符集导致的,我们可以尝试更改使用正确的字符集。常见的字符集如Unicode或者UTF-8等。在LeetCode-Editor,可以在编辑器选择正确的字符集。 3. 使用合适的编辑器:有时候,乱码问题可能与LeetCode-Editor自身相关。我们可以尝试使用其他编码工具,如Text Editor、Sublime Text或者IDE,看是否能够解决乱码问题。 4. 查找特殊字符:如果乱码问题只出现在某些特殊字符上,我们可以尝试找到并替换这些字符。通过仔细检查代码,我们可以找到导致乱码的特定字符,并进行修正或替换。 总之,解决LeetCode-Editor乱码问题的方法有很多。根据具体情况,我们可以尝试更改文件编码格式、使用正确的字符集、更换编辑器或者查找并替换特殊字符等方法来解决这个问题。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值