二叉树的三种遍历方式(递归/非递归)
递归版:
非递归版:
后序遍历的非递归(用2个栈):
后序遍历的非递归(用1个栈):
在二叉树中找到一个节点的后继节点:
思路: 中序遍历 左根右
主要考虑两种情况(有无右孩子节点)
如果该节点 有右孩子节点 , 则是右孩子节点中的最左孩子节点。
没有右孩子节点---则找父节点----直到找到是其父节点左孩子的节点
存在特殊情况: 如果node是整棵二叉树的最后一个节点---则在逐步往上走父节点的时候----可能会走到根节点--- 根节点的父节点为null (有判断父节点是否为空)----所以最后一个节点的后继节点为null
如果题目改为求 一个节点的前驱结点:
考虑 是否有 左孩子节点 ---- 如果 有左孩子节点 ---则前驱结点就是左孩子节点最右节点
如果没有左孩子节点---则往上追溯--只要父节点是当前节点的右孩子即可
二叉树的序列化和反序列化:
按照先序遍历的思路(递归式)
序列化:
反序列化:
按照层序遍历的思路(非递归式)
序列化:
反序列化:
判断一棵二叉树是否是平衡二叉树?
解决这个问题:我们需要充分利用递归的特点
判断一个节点是否平衡 需要获取的信息有: 左平 右平 左高 右高
定义 需要返回的内容信息(是否平衡+ 高度):
开始递归函数的逻辑:
主函数逻辑:
判断一棵树是否是搜索二叉树,判断一棵树是否为完全二叉树?
思路:
搜索二叉树
是 : 根节点的左子树值<根节点的值 右子树的值>根节点的值
所以想到 中序遍历的结果如果是 升序的 则证明是一个二叉搜索树
在非递归中序遍历中 我们记录上一个弹出结果值和当前弹出结果值 比较大小 然后加一个return值
黄色区域改为
if(pre< head.val)
pre=head.val;
else
return false;
XXXXXX
return true;
完全二叉树:
考虑两种逻辑:
1 当前节点有右孩子 没有左孩子 直接返回false
2 当前节点 有左孩子 但是没有右孩子 或者 左右孩子都没有 则 判断后面遇到的节点是否都为叶节点
按层序遍历的思路 :
其中左右判断阶段代码等同于:
已知一棵完全二叉树 ,求其节点个数:
思路:
满二叉树个数: 深度L 总个数为 2L-1 (L为指数)
当前节点标记为X: 一直到左孩子 统计深度
然后找到X的右孩子的最左节点--- 情况1 :如果最左节点已经到了最后一层 (见上图)
则根节点的左节点数目确定2(L-1)-1 +1 =2(L-1)
之后再确定 右孩子的具体个数 ------求和
情况2 :最左节点没有到最后一层 (见下图)
此时右子树是满的 +再确定左边个数--->和 为两部分加起来
总的思路:
bs(以node 为根节点 在level层 h为总的深度(固定值)的完全二叉树的节点个数
最左节点深度到h则计算左边完全二叉树节点个数+递归右边求节点总个数
没到h 则右边完全二叉树节点个数固定 +递归左边求节点总个数
分析时间复杂度: