449. 序列化和反序列化二叉搜索树

本文详细介绍了如何实现449题的序列化和反序列化二叉搜索树的算法,主要涉及二叉树的层次遍历、队列操作以及字符串处理。通过BFS将二叉搜索树转换为字符串,再利用特定规则将字符串还原成原来的树结构。具体实现中,serialize()函数使用层序遍历并以空格分隔,用'#'表示空节点;deserialize()函数则通过strtok()函数解析字符串并构建二叉搜索树。
摘要由CSDN通过智能技术生成

449. 序列化和反序列化二叉搜索树

一、题目

原题链接:449. 序列化和反序列化二叉搜索树]

1.题目描述

序列化是将数据结构或对象转换为一系列位的过程,以便它可以存储在文件或内存缓冲区中,或通过网络连接链路传输,以便稍后在同一个或另一个计算机环境中重建。

设计一个算法来序列化和反序列化 二叉搜索树 。 对序列化/反序列化算法的工作方式没有限制。 您只需确保二叉搜索树可以序列化为字符串,并且可以将该字符串反序列化为最初的二叉搜索树。

编码的字符串应尽可能紧凑。

示例 1:

输入:root = [2,1,3]
输出:[2,1,3]

示例 2:

输入:root = []
输出:[]

提示:

  • 树中节点数范围是 [0, 10^4]
  • 0 <= Node.val <= 10^4
  • 题目数据 保证 输入的树是一棵二叉搜索树。

2.基础框架

C++基础框架代码如下:

string serialize(TreeNode* root){
}

TreeNode* deserialize(string data){
}

3.解题思路

  • 题目分析

serialize()函数的实现思路:

  1. 算法采用BFS,即按层序遍历的顺序访问二叉树的结点,并将结点的值由int类型转换为string类型保存到字符串res中,以" "为分隔符。
  2. 如果当前访问到的是空结点,则以#表示并将#存储到字符串res中,注意#后面要追加
    分隔符" "
  3. 直到队列q为空时,说明二叉树遍历完所有结点,最终得到了序列化字符串res

deserialize()函数的实现思路:

  1. 该函数实现反序列化,也就是将按同一规则的序列化字符串还原成二叉搜索树,所谓的同一规则,也就是在上面serialize()函数中制定的,以" "为分隔符,#表示空结点,并且按层序遍历访问的规则。所以在同一规则的基础上,可以对二叉搜索树进行还原。
  2. 将序列化字符串res中提取出每个访问到的结点所需要的值,这里是通过strtok()函数进行提取,只要以" "为分割符,就会得到原来结点的值,不过还需要将它从字符串转变为整型,所以需要使用atoi()函数。
  3. 提取的值有两种情况,要么是表示空结点的#,要么是字符类型的数字,如果是#则跳过处理。
  4. 如果当前token值不为#,表示该结点不为空结点,那么就将其左、右结点分别添加到队列中。
  5. token为空时,即成功还原二叉搜索树。
  • 实现代码:

    /**
     * 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) {
            if (root == nullptr) return "";
            string res;
            queue<TreeNode*> q;
            q.push(root);
            while (!q.empty())
            {
                TreeNode* node = q.front();
                q.pop();
                if (node)
                    res.append(to_string(node->val) + " ");
                else
                    res.append("# ");
                if (node) 
                {
                    q.push(node->left);
                    q.push(node->right);
                }
            }
            return res;
        }
    
        // Decodes your encoded data to tree.
        TreeNode* deserialize(string data) {
            TreeNode* node = nullptr;
            TreeNode** dummy = &node;
            queue<TreeNode**> q;
            q.push(&node);
            char* token = strtok(const_cast<char*>(data.c_str()), " ");
            while (token)
            {
                int n = q.size();
                for (int j = 0; j < n; ++j)
                {
                    TreeNode** node = q.front();
                    q.pop();
                    if (strcmp(token, "#") != 0)
                    {
                        *node = new TreeNode(atoi(token));
                        q.push(&((*node)->left));
                        q.push(&((*node)->right));
                    }
                    token = strtok(nullptr, " ");
                    if (token == nullptr)
                        break;
                }
            }
            return *dummy;
        }
    };
    
    // Your Codec object will be instantiated and called as such:
    // Codec* ser = new Codec();
    // Codec* deser = new Codec();
    // string tree = ser->serialize(root);
    // TreeNode* ans = deser->deserialize(tree);
    // return ans;
    

4.知识点

  • 二叉树的层次遍历
  • 二叉树的创建
  • 队列
  • 字符串使用strtok()可指定分隔符进行截取。
  • itoa():将整型转换成字符串
  • to_string():将字符串转变成整型

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值