1
/ \
2 3
逐步 Serialize:
讀到 寫入 原因
1 1, root
2 2, 1 的 left
null n, 2 的 left 不存在
null n, 2 的 right 不存在
3 3, 回到 1 後進 1 的 right
null n, 3 的 left 不存在
null n, 3 的 right 不存在
所以:1,2,n,n,3,n,n,
最後兩個 n 都是 3 的小孩:
3
/ \
n n
DFS「回到 1」這件事情是 recursion 自己完成,完全不用寫進字串。
String 裡:"123"實際是三個 character:'1' '2' '3'
但:new TreeNode(...)需要的是:123 // int
所以才要把 '1','2','3' 重建成整數 123。
Tree 拆成文字 → 再把文字一模一樣裝回 Tree。
class Codec {
public:
// ① Serialize:Tree → String
void save(TreeNode* root, string& data) {
if (!root) { // 如果目前節點不存在
data += "n,"; // 用 n 記錄 null
return; // 這條支線結束
}
data += to_string(root->val) + ","; // 先存目前節點
save(root->left, data); // 再存左邊
save(root->right, data); // 最後存右邊
}
string serialize(TreeNode* root) {
string data; // 準備結果字串
save(root, data); // DFS 寫完整棵 Tree
return data; // 回傳序列化結果
}
// ② Deserialize:String → Tree
TreeNode* load(const string& data, int& pos) {
if (data[pos] == 'n') { // 看到 n = null
pos += 2; // 跳過 "n,"
return nullptr; // 這個位置沒有節點
}
int sign = 1; // 預設正數
if (data[pos] == '-') { // 如果看到負號
sign = -1; // 這個數是負數
++pos; // 移到真正的數字
}
int value = 0; // 準備目前節點的數值
while (data[pos] != ',') { // 一直讀到逗號
value = value * 10 + data[pos] - '0'; // 把字元組成整數
++pos; // 往下一個字元
}
++pos; // 跳過逗號
TreeNode* root = new TreeNode(sign * value); // 建立目前節點
root->left = load(data, pos); // 接下來一定重建左邊
root->right = load(data, pos); // 再重建右邊
return root; // 回傳這棵子樹
}
TreeNode* deserialize(string data) {
int pos = 0; // 從字串第一個位置開始
return load(data, pos); // DFS 重建完整 Tree
}
};