每天学习一点算法 2026/04/03
题目:二叉树的序列化与反序列化
序列化是将一个数据结构或者对象转换为连续的比特位的操作,进而可以将转换后的数据存储在一个文件或者内存中,同时也可以通过网络传输到另一个计算机环境,采取相反方式重构得到原数据。
请设计一个算法来实现二叉树的序列化与反序列化。这里不限定你的序列 / 反序列化算法执行逻辑,你只需要保证一个二叉树可以被序列化为一个字符串并且将这个字符串反序列化为原始的树结构。
我这里采用了广度优先的方法遍历存储节点值,遇到空节点时用 # 代替:
typescript
/**
* Definition for a binary tree node.
* class TreeNode {
* val: number
* left: TreeNode | null
* right: TreeNode | null
* constructor(val?: number, left?: TreeNode | null, right?: TreeNode | null) {
* this.val = (val===undefined ? 0 : val)
* this.left = (left===undefined ? null : left)
* this.right = (right===undefined ? null : right)
* }
* }
*/
/*
* Encodes a tree to a single string.
*/
function serialize(root: TreeNode | null): string {
if (!root) return '' // 空树直接返回空字符串
const res = [] // 存储节点值
const queue = [root] // 队列初始放入根节点
while (queue.length > 0) {
const node = queue.shift() // 弹出根节点
res.push(typeof node?.val == 'number' ? node.val : '#') // 记录节点值
if (node) {
// 左右子节点依次入队列
node.left ? queue.push(node.left) : queue.push(null)
node.right ? queue.push(node.right) : queue.push(null)
}
}
return res.join(',') // 返回结果字符串有负数所以需要逗号隔开
};
/*
* Decodes your encoded data to tree.
*/
function deserialize(data: string): TreeNode | null {
if (data.length === 0) return null // 根节点为空的情况直接返回 null
const dataArr = data.split(',') // 分割节点值
const root = new TreeNode(Number(dataArr[0])) // 创建根节点
const pre = [root] // 存放非空节点用于绑定子节点
let preNode = null
for (let i = 1; i < dataArr.length; i++) {
if (i % 2 === 1) {
// 弹出未绑定子节点的节点
preNode = pre.shift()
}
if (dataArr[i] !== '#') {
// 只处理不为空的情况
const node = new TreeNode(Number(dataArr[i]))
// 按序绑定左右子节点
i % 2 === 0 ? preNode.right = node : preNode.left = node
// 保存非空节点
pre.push(node)
}
}
return root
};
/**
* Your functions will be called as such:
* deserialize(serialize(root));
*/
题目来源:力扣(LeetCode)