剑指offer61_序列化二叉树_题解

序列化二叉树

题目描述

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

二叉树的序列化是指:把一棵二叉树按照某种遍历方式的结果以某种格式保存为字符串,从而使得内存中建立起来的二叉树可以持久保存。序列化可以基于先序、中序、后序、层序的二叉树遍历方式来进行修改,序列化的结果是一个字符串,序列化时通过 某种符号表示空节点(#),以 ! 表示一个结点值的结束(value!)。

二叉树的反序列化是指:根据某种遍历顺序得到的序列化字符串结果str,重构二叉树。

例如,我们可以把一个只有根节点为1的二叉树序列化为"1,",然后通过自己的函数来解析回这个二叉树

分析

方案一:层次遍历

序列化 Serialize

借助队列,对二叉树做层序遍历,并将越过叶节点的 \(null\) 也打印出来

算法流程:

  1. 初始化:序列化字符串 \(ret\) , 队列 \(q\) 初始时存放根节点 \(root\)
  2. 层序遍历:\(q\) 为空时跳出循环
    1. 获取二叉树每层的结点个数 \(sz\)
    2. 遍历每层的所有结点
      1. 获取头结点 \(top\)
      2. \(top\) 出队
      3. 判断 \(top\) 是否为空指针
        1. 如果为空,序列化字符串中添加 '#'
        2. 如果不为空,序列化字符串中添加 \(top\) 的节点值 \(top->val\),同时将 \(top\) 的左右孩子结点入队
  3. 返回值:通过 \(ret\) 转换得到的 \(C\) 序列化字符串 \(ans\)

反序列化 Deserialize

利用队列串按层构建二叉树

算法流程:

  1. 初始化:字符流 \(ss\) , 队列 \(q\) 初始时存放根节点 \(root\)
  2. 层序遍历:当 \(q\) 为空时跳出循环
    1. 获取二叉树每层的结点个数 \(sz\)
    2. 遍历每层的所有结点
      1. 获取头结点 \(top\)
      2. \(top\) 出队
      3. 判断 \(top\) 是否为空指针
        1. 如果为空,跳出循环遍历下一个结点
        2. 如果不为空, 调用 \(newNode\)函数新建左右孩子,并让 \(root\) 指向左右孩子,同时将左右孩子入队
  3. 返回根节点 \(root\)

代码

/*
1.时间复杂度:O(n)
2.空间复杂度:O(n)
*/
class Solution
{
public:
    char *Serialize(TreeNode *root)
    {
        string ret = "";
        queue<TreeNode *> q;
        q.push(root);

        while (!q.empty())
        {
            int sz = q.size();
            while (sz--)
            {
                TreeNode *top = q.front();
                q.pop();
                if (top)
                {
                    ret += to_string(top->val);
                    q.push(top->left);
                    q.push(top->right);
                }
                else
                {
                    ret += "#";
                }
                ret += " ";
            }
        }
        char *ans = new char[ret.length() + 1];
        strcpy(ans, ret.c_str());
        return ans;
    }
    TreeNode *newNode(string s)
    {
        TreeNode *Node;
        if (s == "#")
            Node = NULL;
        else
            Node = new TreeNode(stoi(s));
        return Node;
    }
    TreeNode *Deserialize(char *str)
    {
        stringstream ss(str);
        string s;

        ss >> s;
        queue<TreeNode *> q;
        TreeNode *root = newNode(s);
        q.push(root);
        while (!q.empty())
        {
            int sz = q.size();
            while (sz--)
            {
                TreeNode *top = q.front();
                q.pop();
                if (!top)
                    break;
                ss >> s;
                top->left = newNode(s);
                q.push(top->left);
                ss >> s;
                top->right = newNode(s);
                q.push(top->right);
            }
        }
        return root;
    }
};
posted @ 2021-02-27 16:06  RiverCold  阅读(41)  评论(0编辑  收藏  举报