zoukankan      html  css  js  c++  java
  • 刷题——对二进制树进行序列化和反序列化

    原题:

    其实我不怎么会这种类型的题目,所以这里的代码主要参考了九章上面的答案。

    下面是我的代码:

    /**
     * Definition of TreeNode:
     * class TreeNode {
     * public:
     *     int val;
     *     TreeNode *left, *right;
     *     TreeNode(int val) {
     *         this->val = val;
     *         this->left = this->right = NULL;
     *     }
     * }
     */
    
    
    class Solution {
    public:
        vector<string> split(const string &str, string str2del){
            vector<string> res_str;
            int lastindex = 0;
            int index = 0;
            
            while((index = str.find(str2del, lastindex))!=string::npos){
                res_str.push_back(str.substr(lastindex, index-lastindex));
                lastindex = index + str2del.length();
            }
            if(lastindex!=str.length()){
                res_str.push_back(str.substr(lastindex, str.length() - lastindex));
            }
            return res_str;
        }
        /**
         * This method will be invoked first, you should design your own algorithm 
         * to serialize a binary tree which denote by a root node to a string which
         * can be easily deserialized by your own "deserialize" method later.
         */
        string serialize(TreeNode * root) {
            if(root == NULL){
                return "{}";
            }
            vector<TreeNode *> holder;
            holder.push_back(root);
            // cout << holder.size() << endl;
            if(root == NULL){
                return NULL;
            }
            // 用vector来存储节点内容,记住这里左边优先,后面复原的时候会用到
            for(int i = 0; i < holder.size(); i++){
                TreeNode * node = holder[i];
                if (node == NULL){
                    continue;
                }
                holder.push_back(node->left);
                holder.push_back(node->right);
            }
            // 因为节点末端检测的时候会检测到大量的NULL并被添加进holder中,所以需要移除掉
            while(holder[holder.size() - 1]==NULL){
                holder.pop_back();
            }
            string res_str = "{";
            res_str += to_string(holder[0]->val);
            for(int i = 1; i < holder.size(); i++){
                if(holder[i] == NULL){
                    res_str+=",#";
                }
                else{
                    res_str+=",";
                    res_str+=to_string(holder[i]->val);
                }
            }
            res_str+="}";
            return res_str;
        }
    
        /**
         * This method will be invoked second, the argument data is what exactly
         * you serialized at method "serialize", that means the data is not given by
         * system, it's given by your own serialize method. So the format of data is
         * designed by yourself, and deserialize it here as you serialize it in 
         * "serialize" method.
         */
        TreeNode * deserialize(string &data) {
            if(data=="{}") return NULL;
            vector<string> val = split(data.substr(1, data.size() - 2), ",");
            queue<TreeNode *> Q;
            TreeNode *root = new TreeNode(atoi(val[0].c_str()));
            Q.push(root);
            bool isLeftChild=true;
            for(int i=1; i<val.size(); i++){
                if(val[i]!="#"){
                    TreeNode *node = new TreeNode(atoi(val[i].c_str()));
                    if(isLeftChild) Q.front()->left = node;
                    else Q.front()->right = node;
                    Q.push(node);
                }
                if(!isLeftChild){
                    Q.pop();
                }
                // 当执行到右节点时则将当前处理的节点弹出,进入下一个节点(顶->左->右)
                isLeftChild = !isLeftChild;
            }
            return root;
        }
    };
    

    注释里面思路已经说得挺清楚的了,这里只是补充几句。总体上来看其实序列化要简单一点,直接遍历一遍树的内容并按照一定规律转化成字符串就可以了。其实这里用到vectoer是为了方便操作,大概的操作流程是:

    序列化:

    右边就是vector的情况(11之类的只是编号),左边的就是树的结构和内容。序列化的主要思路就是先将遍历一遍binary tree的内容,然后按照一定规律(记住,这里的规律是先左后右,后面反序列化的时候会用到这个规律)保存在vector中。

    反序列化的流程差不多,只是加了个对上一层节点的弹出。

    这里补充下相关的用法:C++ queue(STL queue)用法详解

    虽然是queue的,但是实际上vector的也差不多,最重要的部分其实是这张图:

    大概就是这样。

    本博客文章默认使用CC BY-SA 3.0协议。
  • 相关阅读:
    06_Python的数据类型3元组,集合和字典_Python编程之路
    05_Python的数据类型2列表_Python编程之路
    03_Linux的目录结构_我的Linux之路
    03-第一个脚本程序以及输入输出_Python编程之路
    系统命令学习
    《构建之法》读书笔记
    Android开发入门
    Android 手机进入不了fastboot模式的解决方案
    error:“Unexpected namespace prefix "xmlns" found for tag LinearLayout”
    2014.2.13自我能力量化
  • 原文地址:https://www.cnblogs.com/yejianying/p/serialize_and_deserialize_binary_tree.html
Copyright © 2011-2022 走看看