二叉树序列化到JSON需递归构造{"val":X,"left":...,"right":...}结构,空节点返回"null";关键要判空防段错误、用std::to_string转数值、正确拼接引号与逗号。

二叉树序列化到JSON:用递归+std::string拼接最直接
纯C++不依赖第三方库时,手写JSON序列化是可行的,关键在于统一节点表示逻辑。根节点为空时返回"null",非空则用{"val":X,"left":...,"right":...}结构。
常见错误是忽略空指针边界,导致segfault;或忘记转义数字类型(如把val当字符串拼接,结果变成"val":"42"而非"val":42)。
- 用
std::to_string转换整数,避免引号包裹 - 左/右子树递归结果直接嵌入,不额外加空格(JSON解析器对空白不敏感,但减少体积)
- 若节点含字符串字段(如
std::string name),需手动转义"、、控制字符
std::string to_json(TreeNode* root) {
if (!root) return "null";
return "{\"val\":" + std::to_string(root->val) +
",\"left\":" + to_json(root->left) +
",\"right\":" + to_json(root->right) + "}";
}序列化到XML:用std::ostringstream构造标签更可控
XML比JSON多一层结构约束,必须闭合标签、属性值加引号、文本内容需转义。手写时不建议用printf风格拼接,std::ostringstream能避免类型混淆和缓冲区风险。
容易踩的坑包括:&、、<code>>未转义导致XML解析失败;节点名硬编码成node却忘了和实际类名对齐;空子树输出<left/>还是<left></left>不一致。
立即学习“C++免费学习笔记(深入)”;
使用 JSON Schema 验证 JSON 数据,从示例 JSON 生成 schema,并将其转换为 TypeScript 接口、Python 数据类或 Markdown 文档。
- 定义统一标签名,如
<node val="42"><left>...</left><right>...</right></node> - 空子树输出自闭合标签
<left/>,比空元素更紧凑 - 转义函数只处理
&→&、<→、<code>>→>三处即可(引号由属性包裹逻辑保证)
std::string to_xml(TreeNode* root) {
if (!root) return "";
std::ostringstream oss;
oss << "<node val="" << root->val << "">";
oss << "<left>" << to_xml(root->left) << "</left>";
oss << "<right>" << to_xml(root->right) << "</right>";
oss << "</node>";
return oss.str();
}性能与兼容性:深度优先递归在10⁴级节点下会栈溢出
递归实现简洁,但C++默认栈空间有限。当二叉树退化为链表(单边深度10⁵),to_json大概率触发stack overflow,尤其在Windows MSVC或嵌入式环境。
改用迭代需维护显式栈,结构稍复杂,但能控制内存分配位置(例如用std::vector<std::pair<TreeNode*, int>>模拟调用栈,int标记当前处理阶段)。
- 迭代版JSON序列化中,每个节点压栈两次:一次生成
"{"前缀,一次生成"}"后缀 - XML迭代实现可复用同一栈结构,仅替换标签拼接逻辑
- 若目标平台支持C++17,可用
std::optional<TreeNode*>替代裸指针,提升空值语义清晰度
第三方库接入:json.hpp(nlohmann)比tinyxml2更适配二叉树场景
nlohmann/json 的json类型天然支持嵌套映射和数组,把二叉树转成json j = {{"val", root->val}, {"left", to_json_obj(root->left)}, {"right", to_json_obj(root->right)}}即可自动序列化,且内置UTF-8和浮点精度控制。
tinyxml2需要手动创建XMLDocument、XMLNode,每层都要NewElement、SetAttribute、LinkEndChild,代码量翻倍,且易漏DeleteChildren导致内存泄漏。
- 引入nlohmann只需一个头文件,无编译依赖
- 其
json::dump()默认不缩进,适合网络传输;加参数2可格式化调试用 - 若项目已用Boost.PropertyTree,它也能导出JSON/XML,但语法冗长,且对空节点处理不如nlohmann直观
真正麻烦的从来不是“怎么写”,而是“怎么让空指针、特殊字符、超深树、多线程并发访问”全不出错——这些细节堆叠起来,才决定序列化模块能不能进生产环境。

















