对「树的搜索🌲」的感悟-1

609 阅读2分钟

这是我参与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个大的节点
  • 但是回头想想,我们能否利用树的遍历特性,二叉搜索树的中序遍历就是从大到小排序的
  • 那么我们这道题的突破口就是二叉搜索树的中序遍历

图片.png

  • 在代码中我们可以看到,其实我们在全局维护了一个类似计数器的原理
  • 用c来来计数,重点在make(TreeNode node)函数
  • make(TreeNode node)函数只是简单了沿用了树的中序遍历代码模板
  • 右-中-左,每次在右节点判断完以后,计数器(c)就做减一操作
  • 然后还需注意的就是辅助函数的出口点和特判条件

总结

  1. 虽然这道题是easy难度,但是我们做出来不是目的,而是思考这道题的背后隐藏的逻辑
  2. 从简简单单的这道题能看出,树的三种遍历方式可以应用到很多题目中
  3. 所以往往很小很重要的环节,我们却以为平时用不到