题目描述
设计一个算法来序列化和反序列化二叉搜索树(BST)。要求序列化结果是紧凑的,并能够将该字符串反序列化为原始的二叉搜索树。
题解
这个问题要求我们实现一个算法,能够将二叉搜索树(BST)进行序列化为一个字符串,并能够将这个字符串反序列化为原始的BST。
我们可以使用前序遍历(Preorder Traversal)来实现序列化和反序列化操作。前序遍历按照根节点、左子树、右子树的顺序遍历二叉树。
对于二叉搜索树(BST),使用前序遍历序列化树,然后根据树的中序遍历是有序的性质,从前序遍历中获取中序遍历,最后根据前序遍历和中序遍历来恢复树是一个正确的方法。
代码
class Codec {
public:
// 将BST序列化为字符串(前序遍历)
string serialize(TreeNode* root) {
stringstream ss;
serializeHelper(root, ss);
return ss.str();
}
// 将字符串反序列化为BST
TreeNode* deserialize(string data) {
vector<int> preorder;
vector<int> inorder;
stringstream ss(data);
string token;
while (getline(ss, token, ',')) {
preorder.push_back(stoi(token));
}
// 根据前序遍历重构中序遍历
inorder = preorder;
sort(inorder.begin(), inorder.end());
int preorderIndex = 0;
return buildTree(preorder, inorder, preorderIndex, 0, preorder.size() - 1);
}
private:
// 辅助函数:前序遍历序列化BST
void serializeHelper(TreeNode* root, stringstream& ss) {
if (root == nullptr) {
return;
}
ss << root->val << ",";
serializeHelper(root->left, ss);
serializeHelper(root->right, ss);
}
// 辅助函数:根据前序遍历和中序遍历构建BST
TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder, int& preorderIndex, int inorderStart, int inorderEnd) {
if (preorderIndex >= preorder.size() || inorderStart > inorderEnd) {
return nullptr;
}
int rootValue = preorder[preorderIndex++];
TreeNode* root = new TreeNode(rootValue);
int inorderIndex = find(inorder.begin() + inorderStart, inorder.begin() + inorderEnd, rootValue) - inorder.begin();
root->left = buildTree(preorder, inorder, preorderIndex, inorderStart, inorderIndex - 1);
root->right = buildTree(preorder, inorder, preorderIndex, inorderIndex + 1, inorderEnd);
return root;
}
};