Article Categories
- All Categories
-
Data Structure
-
Networking
-
RDBMS
-
Operating System
-
Java
-
MS Excel
-
iOS
-
HTML
-
CSS
-
Android
-
Python
-
C Programming
-
C++
-
C#
-
MongoDB
-
MySQL
-
Javascript
-
PHP
-
Economics & Finance
Serialize and Deserialize BST in Python
Serialization converts a binary search tree into a string format that can be stored or transmitted, while deserialization reconstructs the tree from that string. This is useful for saving tree data to files or sending it over networks.
Problem Overview
Given a binary search tree, we need to serialize it into a string and then deserialize it back to the original tree structure. The serialization uses level-order traversal with dots as separators and 'N' for null nodes.
Tree Node Class
class TreeNode:
def __init__(self, data, left=None, right=None):
self.data = data
self.left = left
self.right = right
Serialization Method
The serialize method performs level-order traversal and creates a dot-separated string ?
class Codec:
def serialize(self, root):
if not root:
return "N"
result = []
queue = [root]
while queue:
current = queue.pop(0)
if current:
result.append(str(current.data))
queue.append(current.left)
queue.append(current.right)
else:
result.append("N")
# Remove trailing nulls
while result and result[-1] == "N":
result.pop()
return ".".join(result)
Deserialization Method
The deserialize method reconstructs the tree from the serialized string ?
def deserialize(self, data):
if not data or data == "N":
return None
values = data.split(".")
root = TreeNode(int(values[0]))
queue = [root]
i = 1
while queue and i < len(values):
current = queue.pop(0)
# Left child
if i < len(values) and values[i] != "N":
current.left = TreeNode(int(values[i]))
queue.append(current.left)
i += 1
# Right child
if i < len(values) and values[i] != "N":
current.right = TreeNode(int(values[i]))
queue.append(current.right)
i += 1
return root
Helper Functions
def build_tree(values):
"""Build a BST from a list of values"""
if not values:
return None
root = TreeNode(values[0])
queue = [root]
i = 1
while queue and i < len(values):
current = queue.pop(0)
if i < len(values) and values[i] is not None:
current.left = TreeNode(values[i])
queue.append(current.left)
i += 1
if i < len(values) and values[i] is not None:
current.right = TreeNode(values[i])
queue.append(current.right)
i += 1
return root
def inorder_traversal(root):
"""Print inorder traversal of the tree"""
if root:
inorder_traversal(root.left)
print(root.data, end=", ")
inorder_traversal(root.right)
Complete Example
class TreeNode:
def __init__(self, data, left=None, right=None):
self.data = data
self.left = left
self.right = right
class Codec:
def serialize(self, root):
if not root:
return "N"
result = []
queue = [root]
while queue:
current = queue.pop(0)
if current:
result.append(str(current.data))
queue.append(current.left)
queue.append(current.right)
else:
result.append("N")
# Remove trailing nulls
while result and result[-1] == "N":
result.pop()
return ".".join(result)
def deserialize(self, data):
if not data or data == "N":
return None
values = data.split(".")
root = TreeNode(int(values[0]))
queue = [root]
i = 1
while queue and i < len(values):
current = queue.pop(0)
# Left child
if i < len(values) and values[i] != "N":
current.left = TreeNode(int(values[i]))
queue.append(current.left)
i += 1
# Right child
if i < len(values) and values[i] != "N":
current.right = TreeNode(int(values[i]))
queue.append(current.right)
i += 1
return root
def build_tree(values):
if not values:
return None
root = TreeNode(values[0])
queue = [root]
i = 1
while queue and i < len(values):
current = queue.pop(0)
if i < len(values) and values[i] is not None:
current.left = TreeNode(values[i])
queue.append(current.left)
i += 1
if i < len(values) and values[i] is not None:
current.right = TreeNode(values[i])
queue.append(current.right)
i += 1
return root
def inorder_traversal(root):
if root:
inorder_traversal(root.left)
print(root.data, end=", ")
inorder_traversal(root.right)
# Example usage
codec = Codec()
root = build_tree([5, 2, 9, 1, 3, 7])
# Serialize the tree
serialized = codec.serialize(root)
print("Serialized:", serialized)
# Deserialize back to tree
deserialized_root = codec.deserialize(serialized)
print("Deserialized (inorder):", end=" ")
inorder_traversal(deserialized_root)
print()
Serialized: 5.2.9.1.3.7 Deserialized (inorder): 1, 2, 3, 5, 7, 9,
Key Points
- Level-order traversal: Used for serialization to maintain tree structure
- Null representation: 'N' represents null nodes in the serialized string
- Dot separation: Values are separated by dots for easy parsing
- Queue-based reconstruction: Deserialization uses a queue to rebuild the tree level by level
Conclusion
This approach efficiently serializes and deserializes binary search trees using level-order traversal. The serialized format preserves the tree structure and can be easily stored or transmitted across networks.
