---
# System prepended metadata

title: 'LeetCode #449 [Serialize and Deserialize BST](https://leetcode.com/problems/serialize-and-deserialize-bst/)'
tags: [Recursion, LeetCode, Medium, Tree]

---

###### tags: `LeetCode` `Tree` `Recursion` `Medium`
# LeetCode #449 [Serialize and Deserialize BST](https://leetcode.com/problems/serialize-and-deserialize-bst/)
### (Medium)


---
序列化是將數據結構或對象轉換為一系列位的過程，以便它可以存儲在文件或內存緩衝區中，或通過網絡連接鏈路傳輸，以便稍後在同一個或另一個計算機環境中重建。

設計一個算法來序列化和反序列化 二元搜尋樹 。對序列化/反序列化算法的工作方式沒有限制。您只需確保二元搜尋樹可以序列化為字符串，並且可以將該字符串反序列化為最初的二元搜尋樹。

編碼的字符串應盡可能緊湊。


---
撇除序列化/反序列化, 這題的重點在於如何建立preorder traversal, 以及如何用preorder traversal還原tree。
![](https://i.imgur.com/ym6XFNG.png)
有一棵樹長這樣, 則它的preorder traversal為 : 5 [2 1 4] [6 8]

可以先處理左子樹[2 1 4]部分, 而當讀取到[6], 該數大於root->val(5)時就知道左子樹處理完了, 此時返回nullptr。

使用遞迴可以很輕鬆地完成整棵樹的重構。

※reinterpret_cast的使用:可以將某個類型的指標轉為另一類型的指標, 因此可以將int的指標轉為char類型的指標, 並append到string中; 反之也可以從string中取出int, 如下:

```
int val = *reinterpret_cast<const int*>(s.data() + pos);
```
先用s.data()取得string的指標, 並以pos調整位置(4的倍數), 再用reinterpret_cast將char*轉成int*,最後再加上取值符 "*" 取得整數值並存入val中。

---
LeetCode 版本
```
class Codec {
public:
 
    // Encodes a tree to a single string.
    string serialize(TreeNode* root) {
        string s;
        serialize(root, s);
        return s;
    }
 
    // Decodes your encoded data to tree.
    TreeNode* deserialize(string data) {        
        int pos = 0;
        return deserialize(data, pos, INT_MIN, INT_MAX);
    }
private:
    void serialize(TreeNode* root, string& s) {
        if (!root) return;    
        s.append(reinterpret_cast<const char*>(&root->val), sizeof(root->val));
        serialize(root->left, s);
        serialize(root->right, s);
    }
    
    TreeNode* deserialize(const string& s, int& pos, int curMin, int curMax) {
        if (pos >= s.size()) return nullptr;
        int val = *reinterpret_cast<const int*>(s.data() + pos);
        if (val < curMin || val > curMax) return nullptr;
        pos += sizeof(val);
        TreeNode* root = new TreeNode(val);
        root->left = deserialize(s, pos, curMin, val);
        root->right = deserialize(s, pos, val, curMax);
        return root;
    }
};
```