Loading

2023.9.4 序列化和反序列化二叉搜索树

image

上来的思路是序列化按照先序遍历构建字符串,空节点就用"#",每个节点之间用","进行分割。
比如示例1,就可以分割为2,1,#,#,3,#,#
然后反序列化只需要再按照这个字符串先序遍历一次即可。

代码如下:

class Codec {
public:
    string serialize_helper(TreeNode *u, string &str) {
        if (!u) { return ""; }
        str += to_string(u->val);
        str += ",";
        if (u->left) {
            serialize_helper(u->left, str);
        } else {
            str += "#,";
        }
        if (u->right) {
            serialize_helper(u->right, str);
        } else {
            str += "#,";
        }
        return str;
    }

    // Encodes a tree to a single string.
    string serialize(TreeNode* root) {
        if (!root) { return {}; }
        string str;
        auto res = serialize_helper(root, str);
        return res;
    }

    TreeNode* deserialize_helper(const vector<string> &nodes, uint32_t &idx) {
        if (idx >= nodes.size() || nodes[idx] == "#") {
            return nullptr;
        }

        TreeNode *u = new TreeNode();
        u->val = stoi(nodes[idx]);
        u->left = deserialize_helper(nodes, ++idx);
        u->right = deserialize_helper(nodes, ++idx);
        return u;
    }

    // Decodes your encoded data to tree.
    TreeNode* deserialize(string data) {
        if (data.empty()) {
            return nullptr;
        }
        vector<string> nodes;
        string tmp;
        for (char c : data) {
            if (c == ',') {
                nodes.push_back(tmp);
                tmp.clear();
            } else {
                tmp += c;
            }
        }

        uint32_t idx = 0;
        return deserialize_helper(nodes, idx);
    }
};

但是这样实际上完成的是序列化和反序列化二叉树,没有用到BST的性质。
BST有左边比根节点小,右边比根节点大的性质,所以我们可以保存先序遍历的结果,不需要添加"#"来表示空节点。我们反序列化的时候判断当前节点是否比父亲节点小,如果不是,说明它必然是在根节点右边,反之亦然。

posted @ 2023-09-04 10:27  烤肉kr  阅读(5)  评论(0编辑  收藏  举报