Serialize and Deserialize Binary Tree

Sanjeev SharmaSanjeev Sharma
2 min read

Advertisement

Problem

Design a codec to serialize (tree → string) and deserialize (string → tree) a binary tree.

Approach 1 — BFS: Level-order with null markers Approach 2 — DFS Preorder: Compact recursive

Solutions (DFS Preorder)

// C — preorder with '#' for null, ',' as separator (conceptual)
// C++ — DFS Preorder
string serialize(TreeNode* root) {
    if (!root) return "#,";
    return to_string(root->val) + "," + serialize(root->left) + serialize(root->right);
}
TreeNode* deserialize(string data) {
    istringstream iss(data);
    function<TreeNode*()> build = [&]() -> TreeNode* {
        string tok;
        getline(iss, tok, ',');
        if (tok == "#") return nullptr;
        auto node = new TreeNode(stoi(tok));
        node->left = build();
        node->right = build();
        return node;
    };
    return build();
}
// Java — BFS level order
public String serialize(TreeNode root) {
    if (root == null) return "";
    StringBuilder sb = new StringBuilder();
    Queue<TreeNode> q = new LinkedList<>();
    q.add(root);
    while (!q.isEmpty()) {
        TreeNode node = q.poll();
        if (node == null) { sb.append("#,"); continue; }
        sb.append(node.val).append(',');
        q.add(node.left); q.add(node.right);
    }
    return sb.toString();
}
public TreeNode deserialize(String data) {
    if (data.isEmpty()) return null;
    String[] vals = data.split(",");
    TreeNode root = new TreeNode(Integer.parseInt(vals[0]));
    Queue<TreeNode> q = new LinkedList<>();
    q.add(root);
    int i = 1;
    while (!q.isEmpty() && i < vals.length) {
        TreeNode node = q.poll();
        if (!vals[i].equals("#")) { node.left = new TreeNode(Integer.parseInt(vals[i])); q.add(node.left); }
        i++;
        if (i < vals.length && !vals[i].equals("#")) { node.right = new TreeNode(Integer.parseInt(vals[i])); q.add(node.right); }
        i++;
    }
    return root;
}
// JavaScript — DFS preorder
function serialize(root) {
    if (!root) return '#,';
    return root.val + ',' + serialize(root.left) + serialize(root.right);
}
function deserialize(data) {
    const vals = data.split(',');
    let i = 0;
    function build() {
        if (vals[i] === '#') { i++; return null; }
        const node = new TreeNode(parseInt(vals[i++]));
        node.left = build();
        node.right = build();
        return node;
    }
    return build();
}
# Python — DFS preorder
def serialize(root):
    def dfs(node):
        if not node:
            return ['#']
        return [str(node.val)] + dfs(node.left) + dfs(node.right)
    return ','.join(dfs(root))

def deserialize(data):
    vals = iter(data.split(','))
    def build():
        val = next(vals)
        if val == '#':
            return None
        node = TreeNode(int(val))
        node.left = build()
        node.right = build()
        return node
    return build()

Complexity

  • Time: O(n) both
  • Space: O(n)

Key Insight

Preorder serialization with null markers gives enough info to reconstruct uniquely. BFS is more intuitive but DFS is more compact.

Advertisement

Sanjeev Sharma

Written by

Sanjeev Sharma

Full Stack Engineer · E-mopro