題目連結:
題目意譯:
序列化(Serialize)為一道程序,其會將一個資料結構或是一個物件轉換成一個位元序列使其可以被儲存進一個檔案或一個記憶體暫存區,或是經由網路連線傳送到同一臺或是另一個電腦結構後重組回原樣。
請設計一個演算法來序列化以及反序列化(Deserialize)一棵二元樹。你的序列化/反序列化演算法沒有其他的限制,你只需要確保一棵二元樹可以序列化成一個字串,且該字串可以反序列化回到原本的樹狀結構。
額外說明:輸出入的格式與 Leetcode 序列化一棵二元樹之方式一致。你不需遵循著這個格式,所以請盡情發揮創意並自發性地想出別的解法或方式。
限制:
樹中的節點數位於範圍 [0, 10 ^ 4]。
-1000 ≦ Node.val ≦ 1000
範例測資:
範例 1:
輸入: root = [1,2,3,null,null,4,5]
輸出: [1,2,3,null,null,4,5]
範例 2:
輸入: root = []
輸出: []
解題思維:
本題有相當多的解法,以下為其中兩個(後者即為本人程式碼之演算法):
一,根據
這題的論述,我們可以先把給定的二元樹之前序(Preorder)以及中序(Inorder)探訪找出來(數字之間可以用空白、逗號或是其他的符號隔開,本題無限制),然後把這兩個探訪之序列串接在一起並用一個特殊字元作為分辨前、中序序列的方式即可以得到一個序列化後的字串。
至於反序列化就是利用這兩個探訪之序列來把二元樹重建回去(參見前附之鏈結。除了前序 + 中序以外,中序 + 後序(Postorder)也是可行的)。
二,對整棵樹進行一次深度優先搜尋(Depth First Search,DFS)。過程中把遇到的節點值記錄下來,連同指向空節點的那些指標值本身,也就是 NULL,也存起來(這邊是採取先左後右的探訪方式)。把這些節點值以及 NULL (程式碼中是用「#」替代)依照探訪順序串接在一起即是序列化後的字串。例如範例一的二元樹根據本人的程式碼將會被序列化成為 "1 2 # # 3 4 # # 5 # #" 這個字串。
而反序列化就只是遞迴地根據字串把二元樹組回去——看到數字代表是一個節點、看到「#」代表是空節點不應繼續遞迴;而遇到有節點已經有兩個小孩(包含空節點「#」)時,則需要回到上一層的遞迴繼續處理剩下的字串直到結束。
此次分享到此為止,如有任何更加簡潔的想法或是有說明不清楚之地方,也煩請各位大大撥冗討論。