二叉树基本知识:
满二叉树:如果一棵二叉树只有度为0的结点和度为2的结点,并且度为0的结点在同一层上,则这棵二叉树为满二叉树。深度为k,有2^k-1个节点的二叉树。
完全二叉树:除了最底层节点可能没填满外,其余每层节点数都达到最大值,并且最下面一层的节点都集中在该层最左边的若干位置。若最底层为第 h 层(h从1开始),则该层包含 1~ 2^(h-1) 个节点。
二叉搜索树:有数值,二叉搜索树是一个有序树。
- 若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值;
- 若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值;
- 它的左、右子树也分别为二叉排序树
平衡二叉搜索树:又被称为AVL(Adelson-Velsky and Landis)树,且具有以下性质:它是一棵空树或它的左右两个子树的高度差的绝对值不超过1,并且左右两个子树都是一棵平衡二叉树。
顺序存储二叉树:如果父节点的数组下标是 i,那么它的左孩子就是 i * 2 + 1,右孩子就是 i * 2 + 2。
链式存储二叉树:通过指针把分布在各个地址的节点串联一起。
前序遍历preorder:中->左->右
中序遍历inorder:左->中->右
后序遍历postorder:左->右->中
二叉树遍历
145. Binary Tree Postorder Traversal
94. Binary Tree Inorder Traversal
144. Binary Tree Preorder Traversal
递归法:
# 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]:
# Traverse order: middle->left->right
if not root: # if the tree is empty
return []
else:
left = self.preorderTraversal(root.left)
right = self.preorderTraversal(root.right)
return [root.val] + left + right
Tips:对于递归法,中序遍历后续遍历只需要修改return的顺序即可。
迭代法:
preorder:
# 迭代 Iteration
class Solution:
def preorderTraversal(self, root: Optional[TreeNode]) -> List[int]:
if not root:
return []
stack = [root]
result = []
while stack:
node = stack.pop()
result.append(node.val)
if node.right:
stack.append(node.right)
if node.left:
stack.append(node.left)
return result
inorder:
要先记最左的元素,所以在找到最左的元素前之前经过的元素先push到stack里存起来。
# 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 inorderTraversal(self, root: Optional[TreeNode]) -> List[int]:
if not root:
return []
stack = []
result = []
cur = root
while cur or stack:
if cur: # 找到最左的元素,在此之前,持续向stack内push父节点
stack.append(cur)
cur = cur.left
else: # 当当前节点没有叶左节点时,开始pop stack的值
cur = stack.pop() # 把stack的元素pop出
result.append(cur.val)
cur = cur.right # 如果当前节点入栈后有右节点,即将右节点push进stack里,接下来会再pop出,append进result里。
return result
postorder
前序遍历是中左右,后序遍历是左右中。那么可以先取中右左,然后reverse。中左右的写法和前序类似。
# 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 postorderTraversal(self, root: Optional[TreeNode]) -> List[int]:
if not root:
return []
stack = [root]
result = []
while stack:
node = stack.pop()
result.append(node.val)
if node.left:
stack.append(node.left)
if node.right:
stack.append(node.right)
return result[::-1]