iT邦幫忙

2026 iThome 鐵人賽

DAY 12
1
Software Development

快樂演算法系列 第 12

stage update &297 v2

  • 分享至 

  • xImage
  •  

TreeNode* node = 現在 DFS 走到哪個節點
string& str = 把結果持續寫進同一個字串
void = 只負責寫資料,不另外回傳東西

每個 node 看一次 → Serialize
每個資料再讀一次 → Deserialize

最低就是 O(n)

str += to_string(node->val); // 例如 int 12 → string "12"
str.push_back(','); // 再變成 "12,"

Serialize

        Tree
         ↓
        node
       ↙    ↘
    left    right
         ↓
       String
Deserialize

       String
         ↓
        node
       ↙    ↘
    left    right
         ↓
        Tree

"-12,n,n,"讀回來時:看到 '-'→ sign = -1→ 讀 12→ -1 × 12→ -12.還原原始 node value。

6.if (!node) = 目前 node 是空的/不存在(node == nullptr),就代表這裡沒有節點,要記錄 null。

class Codec {
public:
    // Serialize:Tree → String
    void save(TreeNode* node, string& str) {               // node=當下節點,str=整條累積字串
        if (!node) {                                       // 當下節點不存在
            str += "n,";                                   // 記錄 null
            return;                                        // 這條支線結束
        }

        str += to_string(node->val);                       // 把當下 node 的數值加入 str
        str.push_back(',');                                // 加逗號分隔下一份資料

        save(node->left, str);                             // 接著處理左邊
        save(node->right, str);                            // 再處理右邊
    }

    string serialize(TreeNode* node) {                     // 整棵 Tree → String
        string str;                                        // 建立整條結果字串
        str.reserve(80002);                                // 預留空間,減少重新配置
        save(node, str);                                   // 從最上面的 node 開始 DFS
        return str;                                        // 回傳完整字串
    }

    // Deserialize:String → Tree
    TreeNode* load(const string& str, int& strPos) {       // 從 strPos 位置開始重建 node
        if (str[strPos] == 'n') {                          // 目前位置是 null
            strPos += 2;                                   // 跳過 "n,"
            return nullptr;                                // 這裡沒有 node
        }

        int sign = 1;                                      // 預設當下 node 是正數

        if (str[strPos] == '-') {                          // 如果看到負號
            sign = -1;                                     // 記錄為負數
            ++strPos;                                      // 移到真正數字的位置
        }

        int value = 0;// 準備當下 node 的數字部分,正負號由 sign 處理

        while (str[strPos] != ',') {                       // 數字還沒讀完
            value = value * 10 + str[strPos] - '0';        // 字元 → 當下 node 的整數 value
            ++strPos;                                      // str 往下一個位置
        }

        ++strPos;                                          // 跳過逗號

        TreeNode* node = new TreeNode(sign * value);// 合併正負號,還原真正的 node value
        node->left = load(str, strPos);                    // 接著重建左邊
        node->right = load(str, strPos);                   // 再重建右邊

        return node;                                       // 回傳重建完成的這個 node
    }

    TreeNode* deserialize(string str) {                    // 整條 String → Tree
        int strPos = 0;                                    // 從 str 第 0 個位置開始讀
        return load(str, strPos);                          // 開始重建整棵 Tree
    }
};

node = 當下 Tree 節點
str = 整條序列化字串
strPos = str 目前讀到的位置
value = 從 str 讀出的數字部分
sign = 正負號

時間 O(n) 因為每個 node 都只處理一次;空間 O(n)

平衡 Tree:          歪 Tree:
    1                  1
   / \                  \
  2   3                  2
                         \
                          3
                           \
                            4

recursion 深度 recursion 深度
≈ O(log n) = O(n) ← 最壞

兩種 Tree 都要走完所有 node,所以時間都是 O(n);但右邊這種一路沒有分叉,必須同時記住 1→2→3→4...,所以 recursion 空間最壞是 O(n)。


上一篇
200請加油 &297
下一篇
preprocessing v5 & 297 v3
系列文
快樂演算法13
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

1 則留言

0
AndyAWD
iT邦新手 1 級 ‧ 2026-08-31 23:48:22

難不成這是那個樹

我要留言

立即登入留言