LeetCode 297.序列化二叉树 - JavaScript

题目描述

序列化是将一个数据结构或者对象转换为连续的比特位的操做,进而能够将转换后的数据存储在一个文件或者内存中,同时也能够经过网络传输到另外一个计算机环境,采起相反方式重构获得原数据。javascript

请设计一个算法来实现二叉树的序列化与反序列化。这里不限定你的序列 / 反序列化算法执行逻辑,你只须要保证一个二叉树能够被序列化为一个字符串而且将这个字符串反序列化为原始的树结构。java

说明: 不要使用类的成员 / 全局 / 静态变量来存储状态,你的序列化和反序列化算法应该是无状态的。node

序列化二叉树思路

使用广度优先(BFS)遍历全部节点(包括空节点),总体流程以下:git

  1. 初始化字符串 res
  2. 初始化队列 queue,将 root 放入队列
  3. 检查队列是否为空:
    • 队列不为空:取出队首节点,若是节点为 null,那么 res 更新为 res + '#,';若是节点不是 null,那么 res 更新为 res + val,而且将节点的左右节点依次加入 queue。继续循环。
    • 队列为空:结束循环
  4. 返回"[" + res + "]"
1
   / \
  2   3
     / \
    4   5

以上面这棵二叉树为例,它的序列化结果是"[1,2,3,#,#,4,5,#,#,#,#]"github

序列化的代码实现以下:算法

// ac地址:https://leetcode-cn.com/problems/xu-lie-hua-er-cha-shu-lcof/
// 原文地址:https://xxoo521.com/2020-02-13-serialize-and-deserialize-btree/

/**
 * Encodes a tree to a single string.
 *
 * @param {TreeNode} root
 * @return {string}
 */
var serialize = function(root) {
    if (!root) {
        return "[]";
    }

    let res = "";
    let node = root;
    const queue = [node];
    while (queue.length) {
        const front = queue.shift();
        if (front) {
            res += `${front.val},`;
            queue.push(front.left);
            queue.push(front.right);
        } else {
            res += "#,";
        }
    }

    res = res.substring(0, res.length - 1); // 去掉最后一个逗号

    return `[${res}]`;
};

反序列化二叉树思路

之前面的二叉树为例,反序列话就是将字符串"[1,2,3,#,#,4,5,#,#,#,#]"从新还原成原来的二叉树。数组

反序列化流程以下:网络

  • 去掉字符串 res 先后的[],并将其按照,逗号切分获得数组 nodes
  • 初始化队列 queue,放入 nodes 的第一个值对应的节点,nodes 弹出第一个值
  • 检查队列是否为空:
    • 队列不为空。从 queue 取出队首元素。从 nodes 中取出第一个值和第二值,依次处理。继续循环。
    • 队列为空。结束循环。
  • 返回根节点。

反序列化函数的设计关键是:数组 nodes 取出元素的顺序和原二叉树层序遍历的顺序是对应的。数据结构

反序列的函数实现以下:函数

// ac地址:https://leetcode-cn.com/problems/xu-lie-hua-er-cha-shu-lcof/
// 原文地址:https://xxoo521.com/2020-02-13-serialize-and-deserialize-btree/

/**
 * Decodes your encoded data to tree.
 *
 * @param {string} data
 * @return {TreeNode}
 */
var deserialize = function(data) {
    if (data.length <= 2) {
        return null;
    }

    const nodes = data.substring(1, data.length - 1).split(",");
    const root = new TreeNode(parseInt(nodes[0]));
    nodes.shift();

    const queue = [root];
    while (queue.length) {
        const node = queue.shift();
        // 第一个是左节点,节点为空,直接跳过
        const leftVal = nodes.shift();
        if (leftVal !== "#") {
            node.left = new TreeNode(leftVal);
            queue.push(node.left);
        }
        // 第二个是右节点,节点为空,直接跳过
        const rightVal = nodes.shift();
        if (rightVal !== "#") {
            node.right = new TreeNode(rightVal);
            queue.push(node.right);
        }
    }

    return root;
};

更多资料

相关文章
相关标签/搜索