• 面试题37:序列化二叉树(C++)


    题目地址:https://leetcode-cn.com/problems/xu-lie-hua-er-cha-shu-lcof/

    题目描述

    请实现两个函数,分别用来序列化和反序列化二叉树。

    题目示例

    示例: 

    你可以将以下二叉树:

    1
    /
    2 3
    /
    4 5

    序列化为 "[1,2,3,null,null,4,5]"

    解题思路

    BFS+vector:分析题目可以发现,序列化的过程可以采用二叉树层次遍历的方法,即BFS方法,而广度优先搜索一般都使用队列解决,反序列化的过程是可以分为两步,第一步是将单个节点都存储到vector数组中,第二步是利用node_index下标(即左右子树的下标)来连接每个节点,节点i的左子树节点为i+1,右子树节点为i+2,所以,利用广度优先搜索+数组vector可实现序列化和反序列化操作。

    DFS:使用先序序列化二叉树,因为先序遍历(根节点->左子树->右子树)序列构造的二叉树并不是唯一的,若遇到一个空节点,我们使用null表示,由此可序列化二叉树,对于反序列化操作,我们对输入的字符串str进行判断是否为空,若为空,则返回nullptr,否则递归进行反序列化操作。

    程序源码

    BFS+vector

    /**
     * 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) {
            ostringstream cout; //字符串输出流
            queue<TreeNode* > que; //BFS(层次遍历)
            que.push(root); //压入根节点
            while(!que.empty())
            {
                TreeNode* node = que.front(); //获取队列头节点
                if(node == nullptr) cout << "null" << " ";
                else
                   {
                       cout << node->val << " ";
                       que.push(node->left); //压入头节点左节点
                       que.push(node->right); //压入头节点右节点
                   }
                que.pop(); //当前节点出队
            }
            return cout.str();
        }
    
        // Decodes your encoded data to tree.
        TreeNode* deserialize(string data) {
            vector<TreeNode* > list;
            string str_val; //存储每个字符串
            istringstream cin(data);
            while(cin >> str_val) //1.构建单个节点,存入vector
            {
                if(str_val.size() == 0) return nullptr;
                if(str_val == "null") list.push_back(nullptr);
                else 
                    list.push_back(new TreeNode(stoi(str_val)));
            }
            //2.将vector中的节点连接起来
            int node_index = 1; //左右子树下标
            for(int i = 0; i < list.size(); i++)
            {
                if(list[i])
                {
                    list[i]->left = list[node_index++]; //i的左子树
                    list[i]->right = list[node_index++];//i的右子树
                }
            }
            return list[0]; //返回根节点
        }
    };
    /*

      string res;
      queue<TreeNode *> q;
      q.push(root);

      while (!q.empty()) {
        root = q.front();

        q.pop();

      if (root) {
     
       res += to_string(root->val) + ",";
        q.push(root->left);
        q.push(root->right);
      }
      else
        res.push_back(',');
    }

    return res;

    */
    // Your Codec object will be instantiated and called as such:
    // Codec codec;
    // codec.deserialize(codec.serialize(root));

    DFS

    /**
     * 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) {
            ostringstream cout;
            serialize(root, cout);
            return cout.str();      
        }
    
        // Decodes your encoded data to tree.
        TreeNode* deserialize(string data) {
            istringstream cin(data);
            return deserialize(cin);     
        }
    private:
         void serialize(TreeNode* root, ostringstream& cout)
         {
            if(root == nullptr) cout << "null ";
            else
            {
                cout << root->val << " ";
                serialize(root->left, cout);
                serialize(root->right, cout);
            }
        }
            TreeNode* deserialize(istringstream& cin)
            {
                string str;
                cin >> str;
                if(str == "null") return nullptr;
                TreeNode* node = new TreeNode(stoi(str));
                node->left = deserialize(cin);
                node->right = deserialize(cin);
            return node;
        }
    };
    
    // Your Codec object will be instantiated and called as such:
    // Codec codec;
    // codec.deserialize(codec.serialize(root));
    ----------------------------------- 心之所向,素履所往;生如逆旅,一苇以航。 ------------------------------------------
  • 相关阅读:
    C#中设置窗口在最前显示而其他窗口不能使用
    C#中关闭子窗口而不释放子窗口对象的方法
    C#窗体越界时鼠标还能回到初始坐标位置
    C#程序实现软件开机自动启动的两种常用方法
    C# 只开启一个程序,如果第二次打开则自动将第一个程序显示到桌面
    图标库网址收藏
    C# Winform打包部署时添加注册表信息实现开机自启动
    C# winform程序怎么打包成安装项目(VS2010图解)
    数据库的三级范式,涉及范式的问题
    基数排序
  • 原文地址:https://www.cnblogs.com/wzw0625/p/12800269.html
Copyright © 2020-2023  润新知