这是我参与8月更文挑战的第23天,活动详情查看:8月更文挑战
树🌲
遍历
遍历序列构造二叉树:先+中;后+中;层序+中 先序遍历
//根-->左-->右
void PreOrder(BiTree T){
if(T != NULL){
visit(T); //访问根节点
PreOrder(T->lchild); //递归遍历左子树
PreOrder(T->rchild); //递归遍历右子树
}
}
中序遍历
//左-->根-->右
void InOrder(BiTree T){
if(T != NULL){
InOrder(T->lchild); //递归遍历左子树
visit(T); //访问根节点
InOrder(T->rchild); //递归遍历右子树
}
}
后序遍历
//左-->右-->根
void PostOrder(BiTree T){
if(T != NULL){
PostOrder(T->lchild); //递归遍历左子树
PostOrder(T->rchild); //递归遍历右子树
visit(T); //访问根节点
}
}
- 大家对树的遍历肯定烂熟于心了,但是我们要是做树的算法题
- 我们却不会如何去套用树的遍历算法
- 来看题!
- 给定一棵二叉搜索树,请找出其中第k大的节点。
- 输入: root = [3,1,4,null,2], k = 1
3
/ \
1 4
\
2
输出: 4
- 首先拿到这道题,我们应该思考,最笨的方法无非就是
- 维护一个额外的空间,去将树中的所有的节点全都存起来
- 再将问题转换为一个排序数组,找第k个大的节点
- 但是回头想想,我们能否利用树的遍历特性,二叉搜索树的中序遍历就是从大到小排序的
- 那么我们这道题的突破口就是二叉搜索树的中序遍历
- 在代码中我们可以看到,其实我们在全局维护了一个类似计数器的原理
- 用c来来计数,重点在
make(TreeNode node)函数 make(TreeNode node)函数只是简单了沿用了树的中序遍历代码模板- 右-中-左,每次在右节点判断完以后,计数器(c)就做减一操作
- 然后还需注意的就是辅助函数的出口点和特判条件
总结
- 虽然这道题是easy难度,但是我们做出来不是目的,而是思考这道题的背后隐藏的逻辑
- 从简简单单的这道题能看出,树的三种遍历方式可以应用到很多题目中
- 所以往往很小很重要的环节,我们却以为平时用不到