二叉树序列化和反序列化:
预期目标:
序列化:将链表化为类似于 1_ 2_#_ #_ 3 _ #_ #_的形式,#代表指针指向为空。
反序列化:将序列化后的数据还原为二叉树
要点:
1.数据类型转换:int -> string 、string -> int 分别用to_string 和 atoi(x.c_str())实现
2.序列化后数据用队列储存,不使用下标取值,方便运用递归方法。
3.将string数据分解为子string问题。
代码:
参考左神代码编写
#include <iostream>
#include <string>
#include <queue>
using namespace std;
struct Node
{
int value;
Node* left;
Node* right;
Node() : value(0), left(nullptr), right(nullptr) {}
Node(int x) : value(x), left(nullptr), right(nullptr) {}
Node(int x, Node* left, Node* right) : value(x), left(left), right(right) {}
};
// str_spl表示需要分解的字符串,que_save保存分解后的字符串,flag表示分割字符
void split_string(const string& str_spl, queue<string>& que_save, const string& flag)
{
string::size_type pos1 = 0;
string::size_type pos2 = str_spl.find(flag);
while (string::npos != pos2) //pos2 未到达尾部时循环
{
que_save.push(str_spl.substr(pos1, pos2 - pos1));//j将两个分隔符中的字符串压入队列
pos1 = pos2 + flag.size();//移动左指针
pos2 = str_spl.find(flag, pos1);//右指针指向新的分隔符
}
if (pos1 != str_spl.size())//如果队尾还有未入队的元素,则压入队列
{
que_save.push(str_spl.substr(pos1));
}
}
/*
4
/ \
2 7
/ \ /
1 3 5
*/
void creat_bitree(Node*& head)
{
int in;
cout << "int put: ";
cin >> in; // 4 2 1 -1 -1 3 -1 -1 7 5 -1 -1 -1
if (in == -1)
{
head = nullptr;
}
else
{
head = new Node(in);
creat_bitree(head->left);
creat_bitree(head->right);
}
}
string serial_by_pre(Node* head)
{
if (head == nullptr)
{
return "#_";
}
string ret = to_string(head->value) + "_";//to_string将数据类型由intg型转化为string型
ret += serial_by_pre(head->left);
ret += serial_by_pre(head->right);
return ret;
}
Node* recon_pre_order(queue<string>& spl_data)
{
string value = spl_data.front();
spl_data.pop();
if (value == "#")
{
return nullptr;
}
Node* head = new Node(atoi(value.c_str()));//atoi(X.c_str()) 将string型数据转化为int型
head->left = recon_pre_order(spl_data);
head->right = recon_pre_order(spl_data);
return head;
}
void pre_order_recur(Node* head) //先序遍历
{
if (head == nullptr)
{
return;
}
cout << head->value << " ";
pre_order_recur(head->left);
pre_order_recur(head->right);
}
int main()
{
Node* root;
creat_bitree(root);
string data = serial_by_pre(root);
cout << "序列化后结果为: " << endl
<< data << endl;
queue<string> spl_save;
split_string(data, spl_save, "_");
Node* re_new = recon_pre_order(spl_save);
cout << "反序列化后: " << endl;
pre_order_recur(re_new);
return 0;
}