序列化二叉树

描述

  请实现两个函数,分别用来序列化和反序列化二叉树,不对序列化之后的字符串进行约束,但要求能够根据序列化之后的字符串重新构造出一棵与原二叉树相同的树。

  二叉树的序列化(Serialize)是指:把一棵二叉树按照某种遍历方式的结果以某种格式保存为字符串,从而使得内存中建立起来的二叉树可以持久保存。序列化可以基于先序、中序、后序、层序的二叉树等遍历方式来进行修改,序列化的结果是一个字符串,序列化时通过 某种符号表示空节点(#)

  二叉树的反序列化(Deserialize)是指:根据某种遍历顺序得到的序列化字符串结果str,重构二叉树。

例如,可以根据层序遍历的方案序列化,如下图:

  层序序列化(即用函数Serialize转化)如上的二叉树转为"{1,2,3,#,#,6,7}“,再能够调用反序列化(Deserialize)将”{1,2,3,#,#,6,7}"构造成如上的二叉树。

  当然你也可以根据满二叉树结点位置的标号规律来序列化,还可以根据先序遍历和中序遍历的结果来序列化。不对序列化之后的字符串进行约束,所以欢迎各种奇思妙想。

数据范围:节点数 n≤100,树上每个节点的值满足 0≤val≤150

要求:序列化和反序列化都是空间复杂度 O(n)O(n),时间复杂度 O(n)O(n)

示例1

输入:
{1,2,3,#,#,6,7}
返回值:
{1,2,3,#,#,6,7}
说明:
如题面图

示例2

输入:
{8,6,10,5,7,9,11}
返回值:
{8,6,10,5,7,9,11}

解法/思路

方式一

层序序列化。

输入:1,2,3,#,#,6,7

输出:1,2,3,#,#,6,7

/*
struct TreeNode {int val;struct TreeNode *left;struct TreeNode *right;TreeNode(int x) :val(x), left(NULL), right(NULL) {}
};
*/
class Solution {public://序列化char* Serialize(TreeNode *root) {    if(root == nullptr)return nullptr;queue<TreeNode*> nodes;TreeNode* node;int count;string str(to_string(root->val));char* targetStr;if(root->left == nullptr && root->right == nullptr){targetStr = new char;targetStr = (char*)str.c_str();return targetStr;}str += ',';nodes.push(root);while(!nodes.empty()){count = nodes.size();while(count--){node = nodes.front();nodes.pop();if(node->left){nodes.push(node->left);str+=to_string(node->left->val);str+=',';}elsestr+="#,";if(node->right){nodes.push(node->right);str+=to_string(node->right->val);str+=',';}elsestr+="#,";}}for(int i = str.size()-1;i>0;i--){if(str[i] != ',' && str[i] != '#'){str.erase(str.begin()+i+1,str.end());break;}}targetStr = new char[str.length()];strcpy(targetStr, str.c_str());return targetStr;}void SetTree(vector<TreeNode*> nodes,queue<string> &arr){if(arr.empty())return;vector<TreeNode*> arrNode;for(int i=0;i<nodes.size();i++){if(nodes[i] == nullptr)continue;TreeNode* leftNode,*rightNode;if(!arr.empty() && arr.front() != "#"){leftNode = (TreeNode*)malloc(sizeof(TreeNode*));leftNode->val = atoi(arr.front().c_str());}elseleftNode = nullptr;nodes[i]->left = leftNode;if(!arr.empty())arr.pop();if(!arr.empty() && arr.front() != "#"){rightNode = (TreeNode*)malloc(sizeof(TreeNode*));rightNode->val = atoi(arr.front().c_str());}elserightNode = nullptr;nodes[i]->right = rightNode;if(!arr.empty())arr.pop();arrNode.push_back(leftNode);arrNode.push_back(rightNode);}SetTree(arrNode, arr);}//反序列化TreeNode* Deserialize(char *str) {if(str == nullptr)return nullptr;string curStr = str;queue<string> arr;for(int i=0;i<curStr.size();i++){if(curStr[i] == ','){arr.push(string(curStr.begin(),curStr.begin()+i));curStr.erase(curStr.begin(),curStr.begin()+i+1);i = 0;}}arr.push(curStr);TreeNode* node = (TreeNode*)malloc(sizeof(TreeNode*));node->val = atoi(arr.front().c_str());arr.pop();vector<TreeNode*> nodes;nodes.push_back(node);SetTree(nodes, arr);return node;}
};

方式二

使用递归思想,深度递归得到所有的节点并记录。

输入:1,2,#,#,3,6,#,#,7,#,#

输出:1,2,#,#,3,6,#,#,7,#,#

void Serialize(TreeNode* p, string& str)
{if (p == nullptr){str += "#,";return;}str += to_string(p->val);str += ',';Serialize(p->left, str);Serialize(p->right, str);
}//序列化
char* Serialize(TreeNode* root)
{if (root == nullptr)return nullptr;string s;Serialize(root, s);s.erase(s.end() - 1);char* ret = new char[s.length()];strcpy(ret, s.c_str());return ret;
}TreeNode* deserialize(char*& str)
{if (*str == '#'){str += 2;return nullptr;}//建立根结点int num = 0;while (*str != ','){num = num * 10 + (*str - '0');str++;}str++;//递归构建二叉树TreeNode* node = new TreeNode(num);node->left = deserialize(str);node->right = deserialize(str);return node;
}//反序列化
TreeNode* Deserialize(char* str)
{if (str == nullptr)return nullptr;return deserialize(str);
}

序列化二叉树(C++)相关推荐

  1. 剑指offer:面试题37. 序列化二叉树

    题目:序列化二叉树 请实现两个函数,分别用来序列化和反序列化二叉树. 示例:  你可以将以下二叉树: 1    / \   2   3      / \     4   5 序列化为 "[1 ...

  2. 《剑指offer》-- 序列化二叉树、二叉搜索树的第k个节点、数据流中的中位数、滑动窗口的最大值

    一.序列化二叉树: 1.题目: 请实现两个函数,分别用来序列化和反序列化二叉树. 2.解题思路: (1)根据前序遍历规则完成序列化与反序列化.所谓序列化指的是遍历二叉树为字符串:所谓反序列化指的是依据 ...

  3. [二叉树]序列化二叉树 (剑指offer61)

    题目描述 请实现两个函数,分别用来序列化和反序列化二叉树. 解题思路 序列化二叉树:把一棵二叉树按照某种遍历方式的结果以某种格式保存为字符串.需要注意的是,序列化二叉树的过程中,如果遇到空节点,需要以 ...

  4. 剑指 Offer 37. 序列化二叉树

    题目 序列化是将一个数据结构或者对象转换为连续的比特位的操作,进而可以将转换后的数据存储在一个文件或者内存中,同时也可以通过网络传输到另一个计算机环境,采取相反方式重构得到原数据. 请设计一个算法来实 ...

  5. 《剑指Offer》37:序列化二叉树

    题目 请实现两个函数,分别用来序列化和反序列化二叉树. 分析 我们清楚可以通过前序遍历序列和中序遍历序列创造出一棵二叉树.因此,我们可以先把一棵二叉树序列化成一个前序遍历序列和一个中序遍历序列,然后在 ...

  6. 【LeetCode】剑指 Offer 37. 序列化二叉树

    [LeetCode]剑指 Offer 37. 序列化二叉树 文章目录 [LeetCode]剑指 Offer 37. 序列化二叉树 package offer;import java.util.Link ...

  7. 剑指offer(61)序列化二叉树

    题目描述 请实现两个函数,分别用来序列化和反序列化二叉树 题目分析 首先拿到题目时候,我先想到的是什么是序列化二叉树?序列化主要就是在前后端交互时候需要转换下,毕竟网络传输的是流式数据(二进制或者文本 ...

  8. 【重点】剑指offer——面试题62:序列化二叉树

    剑指offer--面试题62:序列化二叉树 Solution1: 参考网址:https://www.nowcoder.com/profile/6475323/codeBookDetail?submis ...

  9. 35-剑指 Offer 37. 序列化二叉树

    题目 请实现两个函数,分别用来序列化和反序列化二叉树. 你需要设计一个算法来实现二叉树的序列化与反序列化.这里不限定你的序列 / 反序列化算法执行逻辑,你只需要保证一个二叉树可以被序列化为一个字符串并 ...

  10. 二叉树(二):判断是不是二叉搜索树、判断是不是完全二叉树、判断是不是平衡二叉树、二叉搜索树的最近公共祖先、在二叉搜索树中找到两个节点的最近公共祖先、序列化二叉树、重建二叉树、输出二叉树的右视图

    目录 一.判断是不是二叉搜索树 1.1 题目 1.2 题解 二.判断是不是完全二叉树 2.1 题目 2.2 题解 三.判断是不是平衡二叉树 3.1 题目 3.2 题解 四.二叉搜索树的最近公共祖先 4 ...

最新文章

  1. jgit查询远程仓库_JAVA 使用jgit管理git仓库
  2. 从搞笑到高效,构建敏捷团队的基础原则
  3. LETTers比赛第三场 --1003 大明A+B解题报告
  4. metric learning
  5. python对文件进行读写操作
  6. [Bzoj]5343: [Ctsc2018]混合果汁
  7. 【flink】Flink 1.12.2 源码浅析 :Task数据输出
  8. 把复杂变简单,能产生颠覆的力量
  9. Java中this关键字的详解
  10. java后台导出word文档正文、表格、图片
  11. oracle怎么恢复误删除的列,三种方式恢复oracle数据库误删除的数据
  12. 2.3两个列表或元组首尾相连
  13. 陕西计算机在职研究生院校排名,陕西在职研究生哪个学校好上
  14. android微信运动页面开发,微信小程序仿微信运动步数排行(交互)
  15. 四面阿里,因为最后一个问题与offer失之交臂
  16. HTML多个单选按钮怎么分组,如何在Excel中对多个选项/单选按钮进行分组?
  17. 2022年第6周(1月31日-2月6日)中国各地区电影票房排行榜:江苏票房夺冠,河南票房环比增幅最大(附热榜TOP31详单)
  18. python爬虫,wallhaven热门壁纸多线程采集下载源码
  19. 欧盟将制定新物联网安全规定
  20. C语言中 -> 是什么意思?

热门文章

  1. 介绍4个大神常用而你不常用的python函数
  2. 一文入门Python 3
  3. pycharm退出测试环境
  4. 村上隆首场中国直播,火山同传打造“影院级字幕”
  5. 利用python进行数据分析—8.数据清洗与准备
  6. python -----class(类)中的object是什么意思?
  7. LeetCode刷题——63. 不同路径 II
  8. 数据结构——树的概述
  9. 博文视点大讲堂25期——2天玩转单反相机
  10. 34线性映射01——映射的概念和性质