問題分析
我們想要序列化二叉樹,可以像Leetcode序列化二叉樹那樣,存儲所有的節點和NULL。
我這裏採用另一種方式,根據二叉樹定義。每一個節點只有一個父節點。所以我們可以將二叉樹變爲一組pair<int, int>
信息,first
表示val
。second
表示父節點的索引。由於單獨僅依靠父節點索引無法辨別其是父節點的左孩子還是右孩子。所以我們使用正負索引來對其進行辨別。索引值爲負數表示其位於父節點左側
代碼
class Codec {
private:
// btArray have a head item, bt.size() == 1 mean bt is empty tree
void codeBtArray(TreeNode* root, int parentLoc, vector<pair<int, int>>& bt)
{
if(!root)
return;
int loc = bt.size();
bt.push_back({root->val, parentLoc});
codeBtArray(root->left, -1 * loc, bt);
codeBtArray(root->right, loc, bt);
}
string serializeBtArray(vector<pair<int, int>>& bt)
{
string btArrayStr;
for(int i = 0; i < bt.size(); i++)
btArrayStr += to_string(bt[i].first) + '|' + to_string(bt[i].second) + ',';
return btArrayStr;
}
vector<pair<int, int>> deserializeBtArray(string btArrayStr)
{
vector<pair<int, int>> btArray;
for(int l = 0, r = btArrayStr.find(',', l); r != string::npos; l = r + 1, r = btArrayStr.find(',', l))
{
int m = btArrayStr.find('|', l);
btArray.push_back({stoi(btArrayStr.substr(l, m - l)), stoi(btArrayStr.substr(m + 1, r - m - 1))});
}
return btArray;
}
TreeNode* decodeBtArray(vector<pair<int, int>> &btArray)
{
if(btArray.size() == 1)
return nullptr;
vector<TreeNode *> btpList(btArray.size());
for(int i = 0; i < btpList.size(); i++)
btpList[i] = new TreeNode(btArray[i].first);
for(int i = 2; i < btpList.size(); i++)
{
if(btArray[i].second < 0)
btpList[-btArray[i].second]->left = btpList[i];
else
btpList[btArray[i].second]->right = btpList[i];
}
return btpList[1];
}
public:
/* 1|0,2|-1,3|1,4|-3,5|3, */
string serialize(TreeNode* root)
{
vector<pair<int, int>> bt = {{0, 0}};
codeBtArray(root, 0, bt);
return serializeBtArray(bt);
}
// Decodes your encoded data to tree.
TreeNode* deserialize(string data) {
vector<pair<int, int>> btArray = deserializeBtArray(data);
return decodeBtArray(btArray);
}
};