题目:序列化二叉树
题目描述
请实现两个函数,分别用来序列化和反序列化二叉树
二叉树的序列化是指:把一棵二叉树按照某种遍历方式的结果以某种格式保存为字符串,从而使得内存中建立起来的二叉树可以持久保存。序列化可以基于先序、中序、后序、层序的二叉树遍历方式来进行修改,序列化的结果是一个字符串,序列化时通过 某种符号表示空节点(#),以 ! 表示一个结点值的结束(value!)。
二叉树的反序列化是指:根据某种遍历顺序得到的序列化字符串结果str,重构二叉树。
吐槽
牛客上面这题的测试用例好菜
class Solution {
public:
TreeNode *hehe;
char* Serialize(TreeNode *root) {
hehe = root;
return "hehe";
}
TreeNode* Deserialize(char *str) {
return hehe;
}
};
思路
用buf数组来存储树的结构,至于返回char *类型,我觉得完全没有必要,不过既然题目要求就顺它意
class Solution {
public:
vector<int> buf;
void dfs(TreeNode *root){
if(root==NULL)
buf.push_back(0xfffff);
else{
buf.push_back(root->val);
dfs(root->left);
dfs(root->right);
}
}
TreeNode *dfs2(int *&p){//&表示把地址传进去,修改函数的算p是全局变量
if(*p==0xfffff) {
p++;
return NULL;
}
TreeNode *r = new TreeNode(*p);
p++;
r->left = dfs2(p);
r->right = dfs2(p);
return r;
}
char* Serialize(TreeNode *root) {
buf.clear();
dfs(root);
int *res = new int[buf.size()];
//int *p = new int[10]; //申请一个动态整型数组,数组的长度为[]中的值
//int p = new int(10); // p指向一个值为10的int数。*
for(int i=0;i<buf.size();i++){
res[i]=buf[i];
}
return (char*) res;
}
TreeNode* Deserialize(char *str) {
int *p = (int *) str;//解码
TreeNode *r = dfs2(p);
return r;
}
};
完整的测试代码:
#include<bits/stdc++.h>
using namespace std;
struct TreeNode{
int val;
TreeNode *left;
TreeNode *right;
TreeNode(int x):
val(x), left(NULL), right(NULL){
}
};
class Solution{
public:
vector<int> buf;
void dfs(TreeNode *root){
if(root==NULL)
buf.push_back(0xfffff);
else{
buf.push_back(root->val);
dfs(root->left);
dfs(root->right);
}
}
TreeNode *dfs2(int *&p){
if(*p==0xfffff) {
p++;
return NULL;
}
TreeNode *r = new TreeNode(*p);
p++;
r->left = dfs2(p);
r->right = dfs2(p);
return r;
}
char* Serialize(TreeNode *root) {
buf.clear();
dfs(root);
int *res = new int[buf.size()];
//int *p = new int[10]; //申请一个动态整型数组,数组的长度为[]中的值
//int p = new int(10); // p指向一个值为10的int数。*
for(int i=0;i<buf.size();i++){
res[i]=buf[i];
}
return (char*) res;
}
TreeNode* Deserialize(char *str) {
int *p = (int *) str;
TreeNode *r = dfs2(p);
return r;
}
// 思路:递归左右子树,找出左右的pre和vin
TreeNode *reConstructBinaryTree(vector<int> pre, vector<int> vin){
int mid, size=pre.size();
if(size==0) return NULL;
TreeNode *root = new TreeNode(pre[0]);
// 找mid的位置
for(int i=0;i<size;i++){
if(pre[0]==vin[i]){
mid=i;break;
}
}
// 定义l_pre,l_vin,r_pre,r_vin;
vector<int> l_pre,l_vin,r_pre,r_vin;
for(int i=0;i<mid;i++){
l_pre.push_back(pre[i+1]);
l_vin.push_back(vin[i]);
}
for(int i=mid+1;i<size;i++){
r_pre.push_back(pre[i]);
r_vin.push_back(vin[i]);
}
//递归找出左右子树
root->left = reConstructBinaryTree(l_pre, l_vin);
root->right = reConstructBinaryTree(r_pre, r_vin);
return root;
}
};
int main(){
// vector<int>p={1,2,4,7,3,5,6,8}, v={4,7,2,1,5,3,8,6};//不对称
vector<int>p={8,6,5,7,10,9,11}, v={5,6,7,8,9,10,11};//对称
Solution s;
//建树
TreeNode *r = s.reConstructBinaryTree(p,v);
char *pp = s.Serialize(r);
int *ppp = (int*) pp;
for(int i=0;i<s.buf.size();i++)
cout<<" "<<ppp[i];
cout<<endl;
TreeNode *r2 = s.Deserialize(pp);
char *pp2 = s.Serialize(r2);
int *ppp2 = (int*) pp2;
for(int i=0;i<s.buf.size();i++)
cout<<" "<<ppp2[i];
cout<<endl;
return 0;
}