• 7 Serialize and Deserialize Binary Tree 序列化及反序列化二叉树


    原题网址:http://www.lintcode.com/zh-cn/problem/serialize-and-deserialize-binary-tree/#

    设计一个算法,并编写代码来序列化和反序列化二叉树。将树写入一个文件被称为“序列化”,读取文件后重建同样的二叉树被称为“反序列化”。

    如何反序列化或序列化二叉树是没有限制的,你只需要确保可以将二叉树序列化为一个字符串,并且可以将字符串反序列化为原来的树结构。

     注意事项

    There is no limit of how you deserialize or serialize a binary tree, LintCode will take your output of serialize as the input of deserialize, it won't check the result of serialize.

    样例

    给出一个测试数据样例, 二叉树{3,9,20,#,#,15,7},表示如下的树结构:

      3
     / 
    9  20
      /  
     15   7
    

    我们的数据是进行BFS遍历得到的。当你测试结果wrong answer时,你可以作为输入调试你的代码。

    你可以采用其他的方法进行序列化和反序列化。

    标签 
     
    思路:序列化二叉树时用广度优先搜素的方法,设置一个队列保存节点,依次遍历。因为空节点无法插入队列,所以用root代替空节点,这样判断当前节点是否为root就可以判断是有效节点还是空节点了。
    注意,该程序结束时字符串尾部会插入多余的‘#’和‘,’,要将这些无效字符删掉。
     
    更新:又测试了下发现NULL可以插入指针队列,emmm……
     
     
    反序列化:依旧是利用队列的先入先出特性,因为要判断新建立的节点是左节点还是右节点,所以再设置一个bool类型的判断标志。
    首先建立根节点,然后遍历字符串,如果当前字符为‘,’就continue;
    如果为‘#’就判断新建立的是左节点还是右节点,如果是右节点代表其根节点已经全部挂载完成,此时需要队列出队,在下一个节点上继续挂载,同时标志反转;
    否则,当前节点为有效数值,首先将这些字符转换成int型数据,然后new出一个二叉树节点,判断挂载在左侧还是右侧,然后标志反转,若是右侧,队列再出队。
     
     
    AC代码:
    注意空字符串要返回""而不是NULL……
    以及,int转string可以用to_string(),但我测试代码时用的VS2010,还不能支持这个函数,所以自己定义了一个。
     
    /**
     * 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:
        /**
         * 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) {
            
            // write your code here
            if (root==NULL)
        {
            return "";//return NULL出错;
        }
        string result;    
        //result=result+to_string(root->val);
        result=result+int2str(root->val);
    
        queue<TreeNode *> level;
        level.push(root->left);
        level.push(root->right);
        
        while(!level.empty())
        {
            TreeNode *temp=level.front();
            level.pop();
            if (temp!=NULL)
            {
                //result=result+","+to_string(temp->val);
                result=result+","+int2str(temp->val);
                level.push(temp->left);
                level.push(temp->right);
            }
            else
            {
                result=result+","+"#";
            }    
        }
    
        int size=result.size();
        int id=size-1;
        while(id>0&&(result[id]=='#'||result[id]==','))
        {
            id--;
        }
        result.resize(id+1);
    
        return result;
        }
    
        /**
         * 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) {
            // write your code here
            if (data.empty())
        {
            return NULL;
        }
    
        int size=data.size();
        int i=0;
        int ro=0;//根节点数值;
        while(data[i]!=','&&i<size)
        {
            char tm=data[i];
            ro=ro*10+tm-'0';
            i++;
        }
        TreeNode * root=new TreeNode(ro); 
        
        queue<TreeNode *> level;
        TreeNode *index=root;    
        bool isLeft=true;
    
        for (;i<size;i++)
        {
            if (data[i]==',')
            {
                continue;
            }
            else if (data[i]=='#')
            {
                if (isLeft)
                {
                    //index->left=NULL;
                    isLeft=false;
                }
                else
                {
                    //index->right=NULL;
                    if (!level.empty())
                    {
                        index=level.front();
                        level.pop();
                    }
                    isLeft=true;
                }    
            }
            else
            {
                int val=0;
                while(i<size&&data[i]!=',') //注意不能写成data[i]!=','&&i<size,因为下标可能超出范围;
                {
                    char temp=data[i];
                    val=val*10+temp-'0';
                    i++;
                }
                
                TreeNode * tempNode=new TreeNode(val);
                level.push(tempNode);
                if (isLeft)
                {
                    index->left=tempNode;
                    isLeft=false;
                }
                else
                {
                    index->right=tempNode;
                    if (!level.empty())
                    {
                        index=level.front();
                        level.pop();
                    }
                    isLeft=true;
                }    
            }        
        }
        return root;
        }
        
        
        string int2str(int &i)
    {
        string str;
        stringstream stream;
        stream<<i;
        str=stream.str();//stream>>str;
        return str;
    }
    
    };
     
     原来的代码……留个纪念。
    /**
     * 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:
        /**
         * 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) {
            
            // write your code here
            if (root==NULL)
        {
            return "";
        }
        string result;    
        //result=result+to_string(root->val);
        result=result+int2str(root->val);
    
        queue<TreeNode *> level;
        if (root->left==NULL&&root->right!=NULL)
        {
            level.push(root);
            level.push(root->right);
        }
        else if (root->left!=NULL&&root->right==NULL)
        {
            level.push(root->left);
            level.push(root);
        }
        else if (root->left!=NULL&&root->right!=NULL)
        {
            level.push(root->left);
            level.push(root->right);
        }
        
        while(!level.empty())
        {
            TreeNode *temp=level.front();
            level.pop();
            if (temp!=root)
            {
                //result=result+","+to_string(temp->val);
                result=result+","+int2str(temp->val);
    
                if (temp->left!=NULL&&temp->right!=NULL)
                {
                    level.push(temp->left);
                    level.push(temp->right);
                }
                else if (temp->left==NULL&&temp->right!=NULL)
                {
                    level.push(root);
                    level.push(temp->right);
                }
                else if (temp->left!=NULL&&temp->right==NULL)
                {
                    level.push(temp->left);
                    level.push(root);
                }
                else 
                {
                    level.push(root);
                    level.push(root);
                }
            }
            else
            {
                result=result+","+"#";
            }    
        }
    
        int size=result.size();
        int id=size-1;
        while(id>0&&(result[id]=='#'||result[id]==','))
        {
            id--;
        }
        result.resize(id+1);
    
        return result;
        }
    
        /**
         * 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) {
            // write your code here
            if (data.empty())
        {
            return NULL;
        }
    
        int size=data.size();
        int i=0;
        int ro=0;//根节点数值;
        while(data[i]!=','&&i<size)
        {
            char tm=data[i];
            ro=ro*10+tm-'0';
            i++;
        }
        TreeNode * root=new TreeNode(ro); 
        
        queue<TreeNode *> level;
        TreeNode *index=root;    
        bool isLeft=true;
    
        for (;i<size;i++)
        {
            if (data[i]==',')
            {
                continue;
            }
            else if (data[i]=='#')
            {
                if (isLeft)
                {
                    //index->left=NULL;
                    isLeft=false;
                }
                else
                {
                    //index->right=NULL;
                    if (!level.empty())
                    {
                        index=level.front();
                        level.pop();
                    }
                    isLeft=true;
                }    
            }
            else
            {
                int val=0;
                while(i<size&&data[i]!=',') //注意不能写成data[i]!=','&&i<size,因为下标可能超出范围;
                {
                    char temp=data[i];
                    val=val*10+temp-'0';
                    i++;
                }
                
                TreeNode * tempNode=new TreeNode(val);
                level.push(tempNode);
                if (isLeft)
                {
                    index->left=tempNode;
                    isLeft=false;
                }
                else
                {
                    index->right=tempNode;
                    if (!level.empty())
                    {
                        index=level.front();
                        level.pop();
                    }
                    isLeft=true;
                }    
            }        
        }
        return root;
        }
        
        
        string int2str(int &i)
    {
        string str;
        stringstream stream;
        stream<<i;
        str=stream.str();//stream>>str;
        return str;
    }
    
    };

    参考:C++中int、string等常见类型转换

    C++中int与string的相互转换

    C++ STL--queue 的使用方法

    其他参考:
     
     
     
  • 相关阅读:
    BootStrap 模态框禁用空白处点击关闭
    【云计算】使用nsenter进入Docker容器进行调试
    【架构】Nginx如何设置X-Request-ID请求头,记录请求时间:毫秒?
    【架构】微服务系列文章
    【云计算】OpenStack项目全面介绍
    【云计算】CloudFoundry参考资料
    【云计算】OpenShift容器服务参考
    【Web】Django OAuth invalid_grant error
    【Linux】Shell三类变量的作用域——linux shell “永久环境变量”、“临时环境变量”和"普通变量"之完全解读
    【云计算】OpenStack Horizon DashBoard定制化,完整实现前后台交互
  • 原文地址:https://www.cnblogs.com/Tang-tangt/p/8916056.html
Copyright © 2020-2023  润新知