LintCode 7 二叉樹的序列化和反序列化
阿新 • • 發佈:2019-01-28
題目:serialize and deserialize
要求:
設計一個演算法,並編寫程式碼來序列化和反序列化二叉樹。將樹寫入一個檔案被稱為“序列化”,讀取檔案後重建同樣的二叉樹被稱為“反序列化”。
如何反序列化或序列化二叉樹是沒有限制的,你只需要確保可以將二叉樹序列化為一個字串,並且可以將字串反序列化為原來的樹結構。
樣例:
給出一個測試資料樣例, 二叉樹{3,9,20,#,#,15,7},表示如下的樹結構:
3
/ \
9 20
/ \
15 7
輸入{1,#,2}
輸出{1,#,2}
演算法要求:
無
解題思路:
需要了解什麼是二叉樹,其序列化和反序列化是什麼。這道題的序列化和反序列化都是用先序遍歷來進行的。首先,我們需要解析字串,提取出有用的部分,存在vector 容器中,再利用create函式進行遞迴建立二叉樹。
本題的難點在於,解析字串和輸出字串的處理。
演算法如下:
public:
string serialize(TreeNode *root) {//反序列化
stringstream data;
data << "{";
data << serialize2(root);
data << "}";
string temp = data.str();
string::iterator itStr;
itStr = temp.end();
itStr-=2 ;
//去除結尾多餘的,和#
while (itStr != temp.begin()) {
if (*itStr == '#') {
temp.erase(itStr);
} else if (*itStr == ',') {
temp.erase(itStr);
} else {
break;
}
itStr--;
}
return temp;
}
TreeNode *deserialize(string data) {//序列化
if (data.size() == 2) {
return NULL;
}
int start = data.find('{', 0);
int end = data.find(',', 0);
nums.clear();//清空容器
string tempStr = data.substr(start + 1, end - start - 1);
//如果沒有找到,相當於到了最後一個數,(start + 1)為數字位置,(data.size()- start - 2)為數字長度
if (end == -1) {
tempStr = data.substr(start + 1, data.size()- start - 2);
} else {
tempStr = data.substr(start + 1, end - start - 1);
}
nums.push_back(tempStr);
while (end != -1) {
start = end;
end = data.find(',', start+1);
//如果沒有找到,相當於到了最後一個數,(start + 1)為數字位置,(data.size()- start - 2)為數字長度
if (end == -1) {
tempStr = data.substr(start + 1, data.size()- start - 2);
} else {
tempStr = data.substr(start + 1, end - start - 1);
}
nums.push_back(tempStr);
}
it = nums.begin();
TreeNode *root = creat(root);
return root;
}
private:
vector<string> nums;
vector<string>::iterator it;
string serialize2(TreeNode *root) {//遞迴先序遍歷,並返回字串
// write your code here
stringstream data;//此為字串流,用法語cout,cin相似,集二者為一體,在這裡用是為了方便操作
if (root == NULL) {
data << "#,";
return data.str();
}
data << root->val << ',';
data << serialize2(root->left);
data << serialize2(root->right);
return data.str();
}
int stoi(string str) {//字串轉化為整型
int num;
stringstream ss;//此為字串流,用法語cout,cin相似,集二者為一體,在這裡用是為了整型轉換
ss << *it;
ss >> num;
return num;
}
TreeNode *creat(TreeNode *bt) {//先序遍歷,遞迴建立
if (it == nums.end()) {//因為序列化需要將多餘的#省略,所以如果字串結束,那麼代表後面全是空結點。
return NULL;
}
if (*it == "#") {
it++;
return NULL;
} else {
bt = new TreeNode(stoi(*it));
it++;
bt->left = creat(bt->left);
bt->right = creat(bt->right);
return bt;
}
}