2021年2月12日金曜日、天気は良いです[過去を嘆いたり、現在を無駄にしたり、未来を恐れたりしないでください]
1.はじめに
ソードフィンガーオファー37.シリアル化されたバイナリツリー
2.解決策
2.1プレオーダートラバーサル(またはポストオーダートラバーサル)
プレオーダートラバーサルは、デシリアライズ中に再帰を適用するのが比較的簡単で、ポストオーダートラバーサルはデシリアライズ中に後ろから前にトラバースでき、順序は「ルート->右->左」になり、コードとプレオーダートラバーサルはわずかな違いです。
次の図に示すように、インオーダートラバーサルによって取得されたバイナリツリーは一意ではなく、逆シリアル化されたバイナリツリーが元のツリーであるとは保証できません。
画像ソースTIM_Y、侵入および削除されました。
事前注文トラバーサルのコードは次のとおりです。
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Codec {
public:
// 序列化递归函数(前序遍历)
void dfs(TreeNode* root, string& s){
if(root==nullptr) s.append("#,");
else{
s.append(to_string(root->val));
s.append(",");
dfs(root->left, s);
dfs(root->right, s);
}
}
// Encodes a tree to a single string.
string serialize(TreeNode* root) {
string s;
dfs(root,s);
return s;
}
// 反序列化递归函数(前序遍历)
void dese(vector<string> &node, int& i, TreeNode* &root){
if(i<node.size()){
if(node[i]=="#"){
++i;
root = nullptr;
return;
}
root = new TreeNode(stoi(node[i]));
++i;
dese(node,i,root->left);
dese(node,i,root->right);
}
}
// Decodes your encoded data to tree.
TreeNode* deserialize(string data) {
// 手动实现split字符串分割函数
vector<string> node;
stringstream ss(data);
string word;
while(getline(ss,word,','))
node.emplace_back(word);
TreeNode* root = nullptr;
int i = 0;
dese(node, i, root);
return root;
}
};
2.2シーケンストラバーサル
シーケンストラバーサル、逆シリアル化が重要なポイントです。最初にツリーが空であると判断し、次にルートノードをチームに配置し、ルートノードの左右の子を配置し、左右かどうかに応じてキューに入るかどうかを決定します。子は空です。子ノードは、ルートノードが経験したプロセスを繰り返します(太字)。
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Codec {
public:
// Encodes a tree to a single string.
string serialize(TreeNode* root) {
string s;
queue<TreeNode*> que;
que.push(root);
while(!que.empty()){
TreeNode* tmp = que.front();
que.pop();
if(tmp==nullptr) s.append("#,");
else{
s.append(to_string(tmp->val));
s.append(",");
que.push(tmp->left);
que.push(tmp->right);
}
}
return s;
}
// Decodes your encoded data to tree.
TreeNode* deserialize(string data) {
if(data.empty() || data[0]=='#') return nullptr;
stringstream ss(data);
vector<string> node;
string word;
while(getline(ss, word, ','))
node.emplace_back(word);
TreeNode* root = new TreeNode(stoi(node[0]));
queue<TreeNode*> que;
que.push(root);
int i = 1;
// 反序列化是重点
while(!que.empty()){
TreeNode* tmp = que.front();
que.pop();
// 安置左孩子
if(node[i]!="#"){
tmp->left = new TreeNode(stoi(node[i]));
que.push(tmp->left);
}
++i;
// 安置右孩子
if(node[i]!="#"){
tmp->right = new TreeNode(stoi(node[i]));
que.push(tmp->right);
}
++i;
}
return root;
}
};
参照
「ソードフィンガーオファー第2版」
https://leetcode-cn.com/problems/xu-lie-hua-er-cha-shu-lcof/solution/mian-shi-ti-37-xu-lie-hua-er-cha-shu-ceng- xu-bian- /
https://www.nowcoder.com/discuss/436465?type=0&order=0&pos=25&page=0&channel=-2&source_id=discuss_center_0