Serialize and Deserialize BST
MEDIUMDescription
Serialization is converting a data structure or object into a sequence of bits so that it can be stored in a file or memory buffer, or transmitted across a network connection link to be reconstructed later in the same or another computer environment.
Design an algorithm to serialize and deserialize a binary search tree. There is no restriction on how your serialization/deserialization algorithm should work. You need to ensure that a binary search tree can be serialized to a string, and this string can be deserialized to the original tree structure.
The encoded string should be as compact as possible.
Example 1:
Input: root = [2,1,3] Output: [2,1,3]
Example 2:
Input: root = [] Output: []
Constraints:
- The number of nodes in the tree is in the range
[0, 104]. 0 <= Node.val <= 104- The input tree is guaranteed to be a binary search tree.
Approaches
Checkout 2 different approaches to solve Serialize and Deserialize BST. Click on different approaches to view the approach and algorithm in detail.
Pre-order Traversal with Null Markers
This approach treats the Binary Search Tree as a general Binary Tree. It serializes the tree using a pre-order traversal, explicitly storing null children with a special marker (e.g., 'N' or '#'). This ensures that the structure can be perfectly reconstructed, but it doesn't take advantage of the BST properties, leading to a less compact string as requested by the problem.
Algorithm
- Serialization:
- Define a recursive function
serializeHelper(node, stringBuilder). - If
nodeisnull, append a null marker (e.g., "N") and a separator to thestringBuilderand return. - Otherwise, append the
node.valand a separator. - Recursively call
serializeHelperfor the left child. - Recursively call
serializeHelperfor the right child.
- Define a recursive function
- Deserialization:
- Split the input string by the separator into a queue of strings.
- Define a recursive function
deserializeHelper(queue). - Dequeue a value from the queue.
- If the value is the null marker, return
null. - Otherwise, create a new
TreeNodewith the parsed value. - Set the node's left child by recursively calling
deserializeHelper(queue). - Set the node's right child by recursively calling
deserializeHelper(queue). - Return the created node.
Serialization
A recursive Depth-First Search (DFS) function, specifically pre-order, is used. The function traverses the tree in the order: root -> left -> right. When a non-null node is encountered, its value is appended to a string builder, followed by a delimiter. When a null pointer is encountered (an empty child), a special marker (e.g., "N") is appended. This process creates a string that uniquely represents the tree structure, including its empty branches.
Deserialization
The serialized string is first split by the delimiter into a list of values. A queue is a natural choice to process these values in the order they were generated. A recursive helper function builds the tree. It dequeues the next value. If the value is the null marker, it returns null. Otherwise, it creates a new node with the parsed integer value. It then recursively calls itself to build the left subtree and then the right subtree, perfectly reconstructing the original tree.
import java.util.Arrays;
import java.util.LinkedList;
import java.util.Queue;
public class Codec {
private static final String SEP = ",";
private static final String NULL = "N";
// Encodes a tree to a single string.
public String serialize(TreeNode root) {
StringBuilder sb = new StringBuilder();
serializeHelper(root, sb);
return sb.toString();
}
private void serializeHelper(TreeNode node, StringBuilder sb) {
if (node == null) {
sb.append(NULL).append(SEP);
return;
}
sb.append(node.val).append(SEP);
serializeHelper(node.left, sb);
serializeHelper(node.right, sb);
}
// Decodes your encoded data to tree.
public TreeNode deserialize(String data) {
if (data == null || data.isEmpty()) {
return null;
}
Queue<String> nodes = new LinkedList<>(Arrays.asList(data.split(SEP)));
return deserializeHelper(nodes);
}
private TreeNode deserializeHelper(Queue<String> nodes) {
String val = nodes.poll();
if (val.equals(NULL)) {
return null;
}
TreeNode node = new TreeNode(Integer.parseInt(val));
node.left = deserializeHelper(nodes);
node.right = deserializeHelper(nodes);
return node;
}
}
Complexity Analysis
Pros and Cons
- Simple to implement and understand.
- Works for any binary tree, not just BSTs.
- The serialized string is not compact because it stores redundant null markers.
- Does not leverage the properties of a BST for optimization.
Code Solutions
Checking out 3 solutions in different languages for Serialize and Deserialize BST. Click on different languages to view the code.
/** * Definition for a binary tree node. * public class TreeNode { * int val; * TreeNode left; * TreeNode right; * TreeNode(int x) { val = x; } * } */ public class Codec { private int i ; private List < String > nums ; private final int inf = 1 << 30 ; // Encodes a tree to a single string. public String serialize ( TreeNode root ) { nums = new ArrayList <>(); dfs ( root ); return String . join ( " " , nums ); } // Decodes your encoded data to tree. public TreeNode deserialize ( String data ) { if ( data == null || "" . equals ( data )) { return null ; } i = 0 ; nums = Arrays . asList ( data . split ( " " )); return dfs (- inf , inf ); } private void dfs ( TreeNode root ) { if ( root == null ) { return ; } nums . add ( String . valueOf ( root . val )); dfs ( root . left ); dfs ( root . right ); } private TreeNode dfs ( int mi , int mx ) { if ( i == nums . size ()) { return null ; } int x = Integer . parseInt ( nums . get ( i )); if ( x < mi || x > mx ) { return null ; } TreeNode root = new TreeNode ( x ); ++ i ; root . left = dfs ( mi , x ); root . right = dfs ( x , mx ); return root ; } } // Your Codec object will be instantiated and called as such: // Codec ser = new Codec(); // Codec deser = new Codec(); // String tree = ser.serialize(root); // TreeNode ans = deser.deserialize(tree); // return ans;Video Solution
Watch the video walkthrough for Serialize and Deserialize BST
Similar Questions
5 related questions you might find useful
Algorithms:
Patterns:
Data Structures:
Subscribe to Scale Engineer newsletter
Learn about System Design, Software Engineering, and interview experiences every week.
No spam, unsubscribe at any time.