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等常见类型转换 

posted @ 2018-12-11 12:13  Timothy_prayer  阅读(928)  评论(0编辑  收藏  举报