• 02.树的序列化与反序列化(C++)


    1.二叉树的序列化

    输入的一棵树:

    //二叉树的先序遍历-序列化
    
    #include <iostream>
    #include <string>
    #include <sstream>
    
    using namespace std;
    
    struct TreeNode {
        int val;
        TreeNode* left;
        TreeNode* right;
        TreeNode(int x) :val(x), left(NULL), right(NULL) {} //构造函数
    };
    
    class Solution {
    public:
        string treeToStr(TreeNode* head) {
            if (head == NULL) {
                return "#_";
            }
            string res = int2str(head->val) + "_";
            res += treeToStr(head->left);
            res += treeToStr(head->right);
            return res;
        }
        //int to string 
        string int2str(const int &int_temp)
        {
            stringstream stream;
            stream << int_temp;
            string string_temp = stream.str();   //此处也可以用 stream>>string_temp
            return string_temp;
        }
    };
    
    int main() {
        //生成一棵二叉树
        TreeNode* head = new TreeNode(3);
        head->left = new TreeNode(1);
        head->right = new TreeNode(5);
        head->left->right = new TreeNode(2);
        head->right->left = new TreeNode(4);
    
        Solution test;
        string s = test.treeToStr(head);
        for (auto c : s) {
            cout << c;
        }
        cout << endl;
        return 0;

    2.二叉树的反序列化

     2.1 上面采用的先序遍历序列化,方便再反序列化回来:

      • 字符串的第一个结点就是根结点;
      • 先序遍历的非递归写法,用栈容易实现;
    class Solution {
    public:
        TreeNode* strToTree(string s) {
            //判空
            int sz = s.size();
            if (sz == 0) return NULL;
    
            //先序遍历,借助栈
            stack<TreeNode*> stack;
            int idx = 0;
            TreeNode* head = new TreeNode((c2i(s[idx])));
            idx = idx + 2;//跳过‘_’分隔符
    
            TreeNode* cur = head;
            while ((cur || !stack.empty() )&& idx<sz) {
                //借助栈,先序遍历        
                if (cur) {
                    stack.push(cur);
                    cur->left = gNode(s[idx]);
                    idx += 2;//跳过‘_’分隔符
                    cur = cur->left;
                }
                else {
                    cur = stack.top();
                    cur->right = gNode(s[idx]);
                    idx += 2;
                    stack.pop();
                    cur = cur->right;
                }
            }
    
            return head;
        }
    
        //generate TreeNode
        TreeNode* gNode(char a) {
            if (a == '#')
                return NULL;
            else {
                return new TreeNode(c2i((a)));
    
            }
        }
    
    
       //char to int 
        int c2i(const char &char_temp)
        {
            stringstream stream;
            stream << char_temp;
            int int_temp;
            stream >> int_temp;
            return int_temp;
        }
    };

    2.2 测试的完整代码,通过字符串还原成树,再输出为字符串,判断是否正确

    //二叉树的反序列化-先序遍历
    
    #include <iostream>
    #include <string>
    #include <sstream>
    #include <stack>
    
    using namespace std;
    
    struct TreeNode {
        int val;
        TreeNode* left;
        TreeNode* right;
        TreeNode(int x) :val(x), left(NULL), right(NULL) {} //构造函数
    };
    
    class Solution1{
    public:
        string serial_Of_Tree(TreeNode* head) {
            if (head == NULL) {
                return "#_";
            }
            string res = int2str(head->val) + "_";
            res += serial_Of_Tree(head->left);
            res += serial_Of_Tree(head->right);
            return res;
        }
        //int to string 
        string int2str(const int &int_temp)
        {
            stringstream stream;
            stream << int_temp;
            string string_temp = stream.str();   //此处也可以用 stream>>string_temp
            return string_temp;
        }
    };
    
    
    class Solution {
    public:
        TreeNode* strToTree(string s) {
            //判空
            int sz = s.size();
            if (sz == 0) return NULL;
    
            //
            stack<TreeNode*> stack;
            int idx = 0;
            TreeNode* head = new TreeNode((c2i(s[idx])));
            idx = idx + 2;
    
            TreeNode* cur = head;
            while ((cur || !stack.empty() )&& idx<sz) {
                        
                if (cur) {
                    stack.push(cur);
                    cur->left = gNode(s[idx]);
                    idx += 2;
                    cur = cur->left;
                }
                else {
                    cur = stack.top();
                    cur->right = gNode(s[idx]);
                    idx += 2;
                    stack.pop();
                    cur = cur->right;
                }
            }
    
            return head;
        }
    
        //generate TreeNode
        TreeNode* gNode(char a) {
            if (a == '#')
                return NULL;
            else {
                return new TreeNode(c2i((a)));
    
            }
        }
    
    
       //char to int 
        int c2i(const char &char_temp)
        {
            stringstream stream;
            stream << char_temp;//stream作为中转站,另外使用<<和>>
            int int_temp;
            stream >> int_temp;
            return int_temp;
        }
    };
    
    int main() {
        string s = "3_1_#_2_#_#_5_4_#_#_#_";
        Solution test1;
        TreeNode* t= test1.strToTree(s);
        Solution1 test;
        string s2 = test.serial_Of_Tree(test1.strToTree(s));
    
        for (auto a : s2) {
            cout << a;
        }
        cout << endl;
        return 0;
    }

    参考资料:

    1.二叉树的序列化和反序列化  (层次遍历,用队列实现的反序列化,java)

    2.C++中int、string等常见类型转换 

  • 相关阅读:
    groovy Date 格式化
    MySql Delete不走索引问题
    java解析文件
    H5自动准备杂记
    ubuntu 安装php ,apache 问题总结
    git 添加已被忽略的文件夹
    jenkins + nodejs + git 自动化部署前端
    分享到微信填坑之路
    jenkins 自动化部署php
    natapp 穿透访问 vue项目 Invalid Host header
  • 原文地址:https://www.cnblogs.com/paulprayer/p/10101409.html
Copyright © 2020-2023  润新知