一.二叉树的遍历
1.二叉树中序遍历
a.递归写法
b.迭代
递归写法很简单,迭代法用到栈stack。
思路是:迭代法,把root放到一个stack里,利用栈后进先出的性质,在迭代中令root=root.left,到了底部之后,从栈中弹出根节点,令root=root.right,达到遍历[左,跟,右]的目的。
2.二叉树的前序遍历
迭代法思路:建立一个栈stack,先root.right,再root.left,弹出的时候就先弹出left,再right.
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution:
def preorderTraversal(self, root: Optional[TreeNode]) -> List[int]:
def dfs(root):
if root:
res.append(root.val)
dfs(root.left)
dfs(root.right)
else:
return
res=[]
dfs(root)
return res
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution:
def preorderTraversal(self, root: Optional[TreeNode]) -> List[int]:
# 前序遍历: 根,左,右
# 用一个stack来记录顺序性,其实递归也是有顺序性的(运行到最后一步,再往前走),用stack来代替递归
if not root:
return []
stack = []
stack.append(root)
res = []
while stack:
node = stack.pop()
res.append(node.val)
if node.right:
stack.append(node.right)
if node.left:
stack.append(node.left)
return res
3.二叉树的后序遍历
# Definition for a binary tree node.
# class TreeNode(object):
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution(object):
def postorderTraversal(self, root):
"""
:type root: TreeNode
:rtype: List[int]
"""
#左 右 根
#前序,根,左,右。
#把前序变成 根,右,左,然后取反
stack=[root]
res=[]
while stack:
node=stack.pop()
if node:
res.append(node.val)
stack.append(node.left)
stack.append(node.right)
return res[::-1]
4.二叉树的层序遍历
二.重建二叉树
1.根据前序遍历和中序遍历构建二叉树
106. 从中序与后序遍历序列构造二叉树
# Definition for a binary tree node.
# class TreeNode(object):
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution(object):
def buildTree(self, inorder, postorder):
"""
:type inorder: List[int]
:type postorder: List[int]
:rtype: TreeNode
"""
#后序:[左,右,跟]
#中序:[左,跟,右]
if not postorder:
return None
root=TreeNode(postorder[-1])
inorder_index=inorder.index(root.val)
root.left=self.buildTree(inorder[:inorder_index],postorder[:inorder_index])
root.right=self.buildTree(inorder[inorder_index+1:],postorder[inorder_index:len(postorder)-1])
return root
三.二叉树的序列化
可以用前序遍历,后序遍历,层序遍历。中序遍历不行,因为找不到根节点。
前序遍历写起来比较方便, 根左右的顺序,列表第一个就是根节点。
297. 二叉树的序列化与反序列化
前序遍历1
思路:前序遍历,遇到叶子节点,返回"#"
二叉树的序列化:把二叉树的节点值用字符串来表示。
二叉树的反序列化:把字符串表示的二叉树节点值,构造成二叉树。
前序遍历2
# 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
"""
#先试一下前序遍历,根,左,右。这样在反序列化的时候,容易找根节点
res=[]
stack=[]
stack.append(root)
while stack:
node=stack.pop()
if not node:
break
if node=="null":
res.append("null")
continue
if node!="null":
res.append(str(node.val))
if node.right:
stack.append(node.right)
else:
stack.append("null")
if node.left:
stack.append(node.left)
else:
stack.append("null")
print(res)
return ','.join(res)
def deserialize(self, data):
"""Decodes your encoded data to tree.
:type data: str
:rtype: TreeNode
"""
#root = [1,2,3,null,null,4,5]
#序列化。[1,2,null,null,3,4,null,null,5,null,null]
#从根节点开始
if len(data)==0:
return
data_list=data.split(",")
print(data_list)
def deserialize2(data):
root_val=data_list.pop(0)
if root_val!="null":
root=TreeNode(int(root_val))
root.left=deserialize2(data)
root.right=deserialize2(data)
return root
return deserialize2(data)
# Your Codec object will be instantiated and called as such:
# ser = Codec()
# deser = Codec()
# ans = deser.deserialize(ser.serialize(root))
层序遍历
428. 序列化和反序列化 N 叉树
前序遍历,并记录child数量
"""
# Definition for a Node.
class Node(object):
def __init__(self, val=None, children=None):
self.val = val
self.children = children
"""
class Codec:
def serialize(self, root: 'Node') -> str:
"""Encodes a tree to a single string.
:type root: Node
:rtype: str
"""
if root == None:
return "#"
data = ""
data += str(root.val) + '-' + str(len(root.children))
for child in root.children:
data += '-' + self.serialize(child)
return data
def deserialize(self, data: str) -> 'Node':
"""Decodes your encoded data to tree.
:type data: str
:rtype: Node
"""
if data == "#":
return None
data = data.split('-')
return self.dfs(data)
def dfs(self, data: List[str]) -> 'Node':
#建root结点
val = int(data.pop(0))
root = Node(val)
root.children = []
#递归儿子们
size = int(data.pop(0))
for _ in range(size):
root.children.append(self.dfs(data))
return root
# Your Codec object will be instantiated and called as such:
# codec = Codec()
# codec.deserialize(codec.serialize(root))
作者:code_learner
链接:https://leetcode-cn.com/problems/serialize-and-deserialize-n-ary-tree/solution/cpython3-1dfs-2bfs-by-hanxin_hanxin-606j/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
449. 序列化和反序列化二叉搜索树
前序遍历
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
#左 < 根 < 右。根,左,右的形式输入的,前序遍历,与一般前序遍历不同的是要存null节点,遍于反序列化找根
class Codec:
def serialize(self, root: TreeNode) -> str:
"""Encodes a tree to a single string.
"""
res = []
def dfs(root):
if not root:
res.append("null")
else:
res.append(str(root.val))
dfs(root.left)
dfs(root.right)
dfs(root)
return "#".join(res)
def deserialize(self, data: str) -> TreeNode:
"""Decodes your encoded data to tree.
"""
if len(data)==0:
return
alist = data.split("#")
def dfs(alist):
root_val = alist.pop(0)
if root_val != "null":
root = TreeNode(root_val)
root.left = dfs(alist)
root.right = dfs(alist)
return root
return dfs(alist)
二叉搜索树的性质,前序+中序构造二叉树
class Codec:
def serialize(self, root):
def preorder(root):
out = []
if root:
out += [str(root.val)]
out += preorder(root.left)
out += preorder(root.right)
return out
return ','.join(preorder(root))
def deserialize(self, data):
if not data:
return None
def buildTree(pre_o, in_o):
if not pre_o:
return None
mid = pre_o[0]
i = in_o.index(mid)
root = TreeNode(mid)
root.left = buildTree(pre_o[1:i + 1], in_o[:i])
root.right = buildTree(pre_o[i + 1:], in_o[i + 1:])
return root
pre_o = list(map(int, data.split(',')))
in_o = sorted(pre_o)
return buildTree(pre_o, in_o)
四.二叉树的深度/平衡二叉树
二叉树的深度
递归写法。左边的深度,右边的深度,取最大值。
平衡二叉树
平衡二叉树,任意节点的子树的高度差都小于等于1。在判断完当前节点是否为平衡二叉树的之后,还要判断他的左右子树实不是平衡二叉树
五.二叉搜索树
230 二叉搜索树中第k小元素
中序遍历
96. 不同的二叉搜索树
深搜
class Solution:
def numTrees(self, n: int) -> int:
#左 < 根 < 右
#递归寻找根节点,乘法原理.左子树小于根节点,右子树大于根节点
@lru_cache(None)
def dfs(left,right):
if left > right:
return 1
#以i为根节点
cur_res = 0
for i in range(left,right+1):
left_count = dfs(left,i-1)
right_count = dfs(i+1,right)
cur_res += left_count * right_count
return cur_res
return dfs(1,n)
97. 不同的二叉搜索树2
递归
class Solution:
def generateTrees(self, n: int) -> List[TreeNode]:
def generateTrees(start, end):
if start > end:
return [None,]
allTrees = []
for i in range(start, end + 1): # 枚举可行根节点
# 获得所有可行的左子树集合
leftTrees = generateTrees(start, i - 1)
# 获得所有可行的右子树集合
rightTrees = generateTrees(i + 1, end)
# 从左子树集合中选出一棵左子树,从右子树集合中选出一棵右子树,拼接到根节点上
for l in leftTrees:
for r in rightTrees:
currTree = TreeNode(i)
currTree.left = l
currTree.right = r
allTrees.append(currTree)
return allTrees
return generateTrees(1, n) if n else []
作者:LeetCode-Solution
链接:https://leetcode.cn/problems/unique-binary-search-trees-ii/solution/bu-tong-de-er-cha-sou-suo-shu-ii-by-leetcode-solut/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
450. 删除二叉搜索树中的节点
利用二叉搜索树的性质,递归
六.二叉树的镜像/对称二叉树
二叉树的镜像
思路:反转左右子树,递归的对左右子树反转。
对称二叉树
思路:不能用镜像二叉树来判断。因为镜像之后,root就变成他的镜像树了,一直是true。
正确的思路是:判断左右子树是否相等,递归的进行。
翻转二叉树
leetcode-树-v2_MaYingColdPlay的博客-CSDN博客
七.二叉树的最近公共祖先
python - 二叉树的最近公共祖先_hotpotbo的博客-CSDN博客_python 二叉树最近公共祖先
剑指offer-leetcode-最大最小问题-思路篇_MaYingColdPlay的博客-CSDN博客
八.trie树
leetcode-数据结构类型的题_MaYingColdPlay的博客-CSDN博客
力扣208
九.二叉树展开为链表
LeetCode 114.二叉树展开为链表(Python实现)_ChungChinKei' blog-CSDN博客
十.树的子结构
366 寻找二叉树的叶子节点
[leetcode] 366. Find Leaves of Binary Tree @ python_tmfighting的博客-CSDN博客