day 11
二叉树理论基础篇 from代码随想录学习
基础知识回顾
二叉树
二叉树类别
满二叉树: 如果一棵二叉树只有0的节点和度为2的节点, 并且度为0的节点在同一层上, 则这棵二叉树为满二叉树。
这棵二叉树为满二叉树,也可以说深度为k,有2^k-1个节点的二叉树。
#完全二叉树
完全二叉树的定义如下:在完全二叉树中,除了最底层节点可能没填满外,其余每层节点数都达到最大值,
并且最下面一层的节点都集中在该层最左边的若干位置。若最底层为第 h 层(h从1开始),则该层包含 1~ 2^(h-1) 个节点。
优先级队列其实是一个堆,堆就是一棵完全二叉树,同时保证父子节点的顺序关系。
二叉搜索树是一个有序树
若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值;
若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值;
它的左、右子树也分别为二叉排序树。
平衡二叉搜索树
平衡二叉搜索树:又被称为AVL(Adelson-Velsky and Landis)树,且具有以下性质:
它是一棵空树或它的左右两个子树的高度差的绝对值不超过1,并且左右两个子树都是一棵平衡二叉树。
二叉树的存储方式
二叉树可以链式存储,也可以顺序存储。
链式存储
class Tree:
def __init__(self, val, left=None, right=None):
self.val = val
self.left == left
self.right = right
顺序存储:
如果父节点的数组下标是 i,那么它的左孩子就是 i * 2 + 1,右孩子就是 i * 2 + 2。
二叉树的遍历方式
深度优先遍历
前序遍历(递归法,迭代法)
中序遍历(递归法,迭代法)
后序遍历(递归法,迭代法)
广度优先遍历
层次遍历(迭代法)
在深度优先遍历中:有三个顺序,前中后序遍历, 有同学总分不清这三个顺序,经常搞混,我这里教大家一个技巧。
这里前中后,其实指的就是中间节点的遍历顺序,只要大家记住 前中后序指的就是中间节点的位置就可以了。
看如下中间节点的顺序,就可以发现,中间节点的顺序就是所谓的遍历方式
前序遍历:中左右
中序遍历:左中右
后序遍历:左右中
栈与队列的一个应用场景:
深度优先: 递归方式--栈其实就是递归的一种实现结构;
广度优先: 层次遍历,一层一层遍历,队列(先进先出)
二叉树的定义
class Tree:
def __init__(self, val, left=None, right=None):
self.val = val
self.left = left
self.right = right
二叉树的递归遍历 代码随想录
递归三部曲
1. 确定递归参数和返回值: 确定哪些参数是递归过程需要处理的, 递归需要返回什么?
2. 确定终止条件:
3. 确定单层递归逻辑: 确定每一层递归需要处理的信息, 哪些信息需要递归重复调用自己来实现递归的过程。
递归前序遍历思路
# 前序遍历的目的: 中左右的方式对二叉树进行遍历,以列表形式返回访问二叉树中的元素顺序。
# 递归的参数和返回值
参数: 二叉树的节点, 返回值: 中左右的形式访问二叉树的元素顺序。
确定终止条件,二叉树的节点为空。
确定单层递归逻辑: 中左右
前序遍历递归 code
class Tree:
def __init__(self, val, left=None, right=None):
self.val = val
self.left = left
self.right = right
result = []
def reverxx(root, result):
# 终止条件
if root == None:
return
# 单层重复的逻辑
result.append(root.val)
reverxx(root.left, result)
reverxx(root.right, result)
中序遍历递归 code
class Tree:
def __init__(self, val, left=None, right=None):
self.val = val
self.left = left
self.right = right
result = []
def reverxx(root, result):
# 终止条件
if root == None:
return
# 单层重复的逻辑
reverxx(root.left, result)
result.append(root.val)
reverxx(root.right, result)
后序遍历递归 code
class Tree:
def __init__(self, val, left=None, right=None):
self.val = val
self.left = left
self.right = right
result = []
def reverxx(root, result):
# 终止条件
if root == None:
return
# 单层重复的逻辑
reverxx(root.left, result)
reverxx(root.right, result)
result.append(root.val)
二叉树的迭代遍历 代码随想录
层序遍历
迭代法,非递归实现二叉树的前中后序遍历。
递归: 每次递归调用都会把函数的局部遍历、参数和返回地址等压入调用栈中, 然后递归返回时,
从栈顶弹回上一次递归的各项参数,所以,可以用栈来实现二叉树的前中后序遍历。
非递归 前序遍历思路
前序遍历: 中左右的顺序。 每次先处理中节点。
先把根节点加入栈, 根据栈的思想, 先进后出= 后进先出; 中左右, 我们需要先处理左子树,再处理右子树;
如果先左子树入栈、再右子树入栈,则在栈框架下,会先处理右子树而非左子树,所以,需要先加入右子树、再左子树;
这样就会先处理左子树, oh yeah.
显然 处理这个栈是一个循环且无法事先知道终止节点,使用while.
1. 先把root入栈
while中
先弹出最后一个节点
收集该节点的数值
右节点入栈
左节点入栈
code
class Tree:
def __init__(self, val, left=None, right=None):
self.val = val
self.left = left
self.right = right
result = []
root = Tree
stack = [root]
while stack:
# 因为是中左右方式遍历数据, 所以当前遇到的就是中,可以先判读数据是否为空,加入值到
root = stack.pop() # 弹出最后一个元素
# 先把值收集起来
result.append(root.val)
# 右左入栈
stack.append(root.right)
stack.append(root.left)