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;
};

更多資料

相關文章
相關標籤/搜索