面试题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));
----------------------------------- 心之所向,素履所往;生如逆旅,一苇以航。 ------------------------------------------
原文地址:https://www.cnblogs.com/wzw0625/p/12800269.html