LeetCode 序列化和反序列化二叉搜索树

序列化是将数据结构或对象转换为一系列位的过程,以便它可以存储在文件或内存缓冲区中,或通过网络连接链路传输,以便稍后在同一个或另一个计算机环境中重建。
设计一个算法来序列化和反序列化二叉搜索树。 对序列化/反序列化算法的工作方式没有限制。 您只需确保二叉搜索树可以序列化为字符串,并且可以将该字符串反序列化为最初的二叉搜索树。
编码的字符串应尽可能紧凑。
注意:不要使用类成员/全局/静态变量来存储状态。 你的序列化和反序列化算法应该是无状态的。
思路分析:请先翻阅 LeetCode 二叉树的序列化与反序列化
由于二叉搜索树是二叉树的一种特殊情况,所以直接套用上题的代码即可。

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Codec {
public:
    // Encodes a tree to a single string.
    string serialize(TreeNode* root) {
        string result = "[";
		queue<TreeNode*> myQue;//层次遍历辅助队列
		myQue.push(root);
		while (!myQue.empty()) {
			root = myQue.front();
			myQue.pop();
			if (root == NULL) {//特殊情况
				result += "null,";
				continue;
			}
			else {//这里不管左右子树是否为空,都需要入队列
				result += to_string(root->val) + ",";
                myQue.push(root->left);
			    myQue.push(root->right);
			}
		}    
        //示例给出的序列化字符串为"[1,2,3,null,null,4,5]"
        //而按照上面的层次遍历得到的结果是"[1,2,3,null,null,4,5,null,null,null,null]"
        //因为当访问到最底层的节点时,左右子树不管都为空,任然会进入队列。
        
        //所以下面需要进行处理
		if (result == "[null,") {//如果这棵树为空,只需要去逗号
			result.resize(result.size() - 1);
		}
		else {//否则需要去掉多余的逗号、null
			int endIndex = result.size() - 1;
			//需要去掉末尾的逗号和多余的null
			while (result[endIndex] < '0' || result[endIndex] > '9') {
				endIndex -= 1;
			}
			result.resize(endIndex + 1);
		}
        result += "]";//最后别忘记了右括号
		return  result;
    }

    // Decodes your encoded data to tree.
    TreeNode* deserialize(string data) {
        //首先将data字符串以逗号进行分割
		vector<string> dataVec;//data以逗号分隔开
		int dataSize = data.size();
		//取出中间的数据(null转换为INT_MIN
		for (int index = 1; index < dataSize - 1; ++index) {
			string tempData = "";
            //一直复制,直到遇到逗号
			while (index < dataSize - 1 && data[index] != ',') {
				tempData += data[index++];
			}
			dataVec.push_back(tempData);
		}
		//将层次遍历序列序列化为二叉树
		int dataVecSize = dataVec.size();
		queue<TreeNode*> myQue;//反序列化的辅助队列
		//层次遍历只为空节点的特殊情况
		if (dataVec[0] == "null") {
			return NULL;
		}
		TreeNode *result = new TreeNode(atoi(dataVec[0].c_str())), *tempPtr;//根节点,atoi(dataVec[0].c_str()转化为int
		myQue.push(result);
		for (int index = 1; index < dataVecSize; ++index) {
			tempPtr = myQue.front();//获取下一个即将构建的节点
			myQue.pop();
			//构建左子树
			if (dataVec[index] != "null") {
				tempPtr->left = new TreeNode(atoi(dataVec[index].c_str()));
				myQue.push(tempPtr->left);//记得要放入队列,因为左子树可能还需要构造
			}
			index += 1;//dataVec指针后移
			//构建右子树
			if (index < dataVecSize && dataVec[index] != "null") {
				tempPtr->right = new TreeNode(atoi(dataVec[index].c_str()));
				myQue.push(tempPtr->right);//记得要放入队列,因为右子树可能还需要构造
			}
		}
		return result;
    }
};

// Your Codec object will be instantiated and called as such:
// Codec codec;
// codec.deserialize(codec.serialize(root));

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/qq_41855420/article/details/88871059