1. 程式人生 > 其它 >二叉樹序列化和反序列化

二叉樹序列化和反序列化

二叉樹的序列化和反序列化

1. 二叉樹序列化:

(a) 如果當前的樹為空,則表示成X

(b) 如果當前的樹不為空,則表示成(<left_sub_tree>)cur_num(<right_sub_tree>),其中,

<left_sub_tree>: 是左子樹序列化後的結果

<right_sub_tree>: 是右子樹序列化後的結果

cur_num: 當前節點的值

中序遍歷可以得到序列化的結果。

2. 二叉樹的反序列化

根據二叉樹序列化,我們可以推匯出這樣的巴科斯正規化:

T -> (T) num (T) | x

用T代表一棵樹序列化的結果,| 表示T構成的為(T) num (T) 或者X,| 左邊是對T的遞迴定義,右邊規定了遞迴終止的邊界條件。

T 的定義中,序列中的第一個字元要麼是 X,要麼是 (,所以這個定義是不含左遞迴的,當我們開始解析一個字串的時候,如果開頭是 X,我們就知道這一定是解析一個「空樹」的結構,如果開頭是 (,我們就知道需要解析 (T) num (T) 的結構,因此這裡兩種開頭和兩種解析方法一一對應,可以確定這是一個無二義性的文法

我們只需要通過開頭的第一個字母是 X 還是 ( 來判斷使用哪一種解析方法,所以這個文法是 LL(1) 型文法,如果你不知道什麼是 LL(1) 型文法也沒有關係,你只需要知道它定義了一種遞迴的方法來反序列化,也保證了這個方法的正確性——我們可以設計一個遞迴函式:

這個遞迴函式傳入兩個引數,帶解析的字串和當前當解析的位置 ptr,ptr 之前的位置是已經解析的,ptr 和 ptr 後面的字串是待解析的。如果當前位置為 X 說明解析到了一棵空樹,直接返回。否則當前位置一定是 (,對括號內部按照 (T) num (T) 的模式解析

class Codec {

public:

string serialize(TreeNode* root) {

if (!root) {

return "X";

}

auto left = "(" + serialize(root->left) + ")";

auto right = "(" + serialize(root->right) + ")";

return left + to_string(root->val) + right;

}

inline TreeNode* parseSubtree(const string &data, int &ptr) {

++ptr; // 跳過左括號

auto subtree = parse(data, ptr);

++ptr; // 跳過右括號

return subtree;

}

inline int parseInt(const string &data, int &ptr) {

int x = 0, sgn = 1;

if (!isdigit(data[ptr])) {

sgn = -1;

++ptr;

}

while (isdigit(data[ptr])) {

x = x * 10 + data[ptr++] - '0';

}

return x * sgn;

}

TreeNode* parse(const string &data, int &ptr) {

if (data[ptr] == 'X') {

++ptr;

return nullptr;

}

auto cur = new TreeNode(0);

cur->left = parseSubtree(data, ptr);

cur->val = parseInt(data, ptr);

cur->right = parseSubtree(data, ptr);

return cur;

}

TreeNode* deserialize(string data) {

int ptr = 0;

return parse(data, ptr);

}

};

3.複雜度分析

時間複雜度:序列化時做了一次遍歷,漸進時間複雜度為 O(n)O(n)。反序列化時,在解析字串的時候 ptr 指標對字串做了一次順序遍歷,字串長度為 O(n)O(n),故這裡的漸進時間複雜度為 O(n)O(n)。

空間複雜度:考慮遞迴使用的棧空間的大小,這裡棧空間的使用和遞迴深度有關,遞迴深度又和二叉樹的深度有關,在最差情況下,二叉樹退化成一條鏈,故這裡的漸進空間複雜度為 O(n)O(n)。

摘自:https://leetcode-cn.com/problems/serialize-and-deserialize-binary-tree/solution/er-cha-shu-de-xu-lie-hua-yu-fan-xu-lie-hua-by-le-2