一、题目描述
https://leetcode-cn.com/problems/serialize-and-deserialize-binary-tree/
请实现两个函数,分别用来序列化和反序列化二叉树
二叉树的序列化是指:把一棵二叉树按照某种遍历方式的结果以某种格式保存为字符串,从而使得内存中建立起来的二叉树可以持久保存。
序列化可以基于先序、中序、后序、层序的二叉树遍历方式来进行修改,序列化的结果是一个字符串,序列化时通过 某种符号表示空节点(#),以 ! 表示一个结点值的结束(value!)。
二叉树的反序列化是指:根据某种遍历顺序得到的序列化字符串结果str,重构二叉树。
二、代码详解(二叉树见上图)
力扣版
2.1 BFS(层序遍历:O(N)、O(N))
- 序列化后的字符串: 1,2,3,4,#,5,6,#,#,#,#,#,#
- 反序列化后的根节点值: 1
# Definition for a binary tree node.
class TreeNode(object):
def __init__(self, x):
self.val = x
self.left = None
self.right = None
from collections import deque
class Codec:
def serialize(self, root):
"""Encodes a tree to a single string.
:type root: TreeNode
:rtype: str
"""
if not root:
return ""
res = []
queue = deque([root])
while queue:
node = queue.popleft()
if node != None:
queue.append(node.left)
queue.append(node.right)
res.append(str(node.val))
else:
res.append("#")
return ",".join(res)
def deserialize(self, data):
"""Decodes your encoded data to tree.
:type data: str
:rtype: TreeNode
"""
if data == '': # 必须加,不然ac不了
return None
datas = data.split(",") # str.split
# print(type(datas)) # <class 'list'>
idx = 0
val = datas[idx]
if val == "#":
return None
root = TreeNode(int(val)) # 根节点
queue = deque([root])
while queue:
node = queue.popleft()
idx += 1
val = datas[idx]
if val != "#":
node.left = TreeNode(int(val))
queue.append(node.left)
idx += 1
val = datas[idx]
if val != "#":
node.right = TreeNode(int(val))
queue.append(node.right)
return root
# Your Codec object will be instantiated and called as such:
pRoot1 = TreeNode(1)
pRoot2 = TreeNode(2)
pRoot3 = TreeNode(4)
pRoot4 = TreeNode(3)
pRoot5 = TreeNode(5)
pRoot6 = TreeNode(6)
pRoot1.left = pRoot2
pRoot1.right = pRoot4
pRoot2.left = pRoot3
pRoot4.left = pRoot5
pRoot4.right = pRoot6
codec = Codec()
serializeStr = codec.serialize(pRoot1)
print('序列化后的字符串:', serializeStr)
print('反序列化后的根节点值:', codec.deserialize(serializeStr).val)
# 序列化后的字符串: 1,2,3,4,#,5,6,#,#,#,#,#,#
# 反序列化后的根节点值: 1
2.2 DFS(前序遍历)
- 序列化后的字符串: 1,2,4,#,#,#,3,5,#,#,6,#,#
- 反序列化后的根节点值: 1
# Definition for a binary tree node.
class TreeNode(object):
def __init__(self, x):
self.val = x
self.left = None
self.right = None
class Codec:
def serialize(self, root):
"""Encodes a tree to a single string.
:type root: TreeNode
:rtype: str
"""
def dfs(node): # preOrder
if node:
retList.append(str(node.val))
dfs(node.left)
dfs(node.right)
else:
retList.append("#")
retList = []
dfs(root)
return ",".join(retList)
def deserialize(self, data):
"""Decodes your encoded data to tree.
:type data: str
:rtype: TreeNode
"""
retList = data.split(',')
if retList == []:
return None
def dfs():
rootVal = retList[0]
del retList[0]
if rootVal == '#':
return None
node = TreeNode(int(rootVal))
node.left = dfs()
node.right = dfs()
return node
root = dfs()
return root
# 迭代器iter、next写法
# def deserialize(self, data):
# """Decodes your encoded data to tree.
#
# :type data: str
# :rtype: TreeNode
# """
#
# def dfs(): # dePreOrder
# v = next(vals)
# if v == "#":
# return None
# node = TreeNode(int(v))
#
# node.left = dfs()
# node.right = dfs()
# return node
#
# vals = iter(data.split(","))
# return dfs()
迭代器写法:实现反序列化
iter() 函数用来生成迭代器 https://www.runoob.com/python/python-func-iter.html
next() 返回迭代器的下一个项目。next() 函数要和生成迭代器的iter() 函数一起使用。https://www.runoob.com/python/python-func-next.html
# Your Codec object will be instantiated and called as such:
pRoot1 = TreeNode(1)
pRoot2 = TreeNode(2)
pRoot3 = TreeNode(4)
pRoot4 = TreeNode(3)
pRoot5 = TreeNode(5)
pRoot6 = TreeNode(6)
pRoot1.left = pRoot2
pRoot1.right = pRoot4
pRoot2.left = pRoot3
pRoot4.left = pRoot5
pRoot4.right = pRoot6
codec = Codec()
serializeStr = codec.serialize(pRoot1)
print('序列化后的字符串:', serializeStr)
print('反序列化后的根节点值:', codec.deserialize(serializeStr).val)
# 序列化后的字符串: 1,2,4,#,#,#,3,5,#,#,6,#,#
# 反序列化后的根节点值: 1
- 时间复杂度:在序列化和反序列化函数中,只访问每个节点一次,时间复杂度为 O(n),其中 n 是节点数,即树的大小。
- 空间复杂度:在序列化和反序列化函数中,递归会使用栈空间,故渐进空间复杂度为 O(n)。
2.3 剑指版(DFS版)
# -*- coding:utf-8 -*-
class TreeNode:
def __init__(self, x):
self.val = x
self.left = None
self.right = None
class Solution:
def Serialize(self, root):
# write code here
retList = []
def preOrder(root):
if root == None:
retList.append('#')
return
retList.append(str(root.val))
preOrder(root.left)
preOrder(root.right)
preOrder(root)
return ' '.join(retList)
def Deserialize(self, s):
# write code here
retList = s.split()
if retList == []:
return None
def dePreOrder():
rootVal = retList[0]
del retList[0]
if rootVal == '#':
return None
node = TreeNode(int(rootVal))
leftNode = dePreOrder()
rightNode = dePreOrder()
node.left = leftNode
node.right = rightNode
return node
pRoot = dePreOrder()
return pRoot
pRoot1 = TreeNode(1)
pRoot2 = TreeNode(2)
pRoot3 = TreeNode(4)
pRoot4 = TreeNode(3)
pRoot5 = TreeNode(5)
pRoot6 = TreeNode(6)
pRoot1.left = pRoot2
pRoot1.right = pRoot4
pRoot2.left = pRoot3
pRoot4.left = pRoot5
pRoot4.right = pRoot6
s = Solution()
serializeStr = s.Serialize(pRoot1)
print('序列化后的字符串:', serializeStr)
print('反序列化后的根节点值:', s.Deserialize(serializeStr).val)
结果输出
序列化后的字符串: 1 2 4 # # # 3 5 # # 6 # #
反序列化后的根节点值: 1